1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is Mozilla XPCOM.
16 * The Initial Developer of the Original Code is
17 * Benjamin Smedberg <benjamin@smedbergs.us>.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsVersionComparator.h"
44 #include "nsStringGlue.h"
50 const char *strB
; // NOT null-terminated, can be a null pointer
55 char *extraD
; // null-terminated
62 const PRUnichar
*strB
; // NOT null-terminated, can be a null pointer
67 PRUnichar
*extraD
; // null-terminated
73 * Parse a version part into a number and "extra text".
75 * @returns A pointer to the next versionpart, or null if none.
78 ParseVP(char *part
, VersionPart
&result
)
86 result
.extraD
= nsnull
;
91 dot
= strchr(part
, '.');
95 if (part
[0] == '*' && part
[1] == '\0') {
96 result
.numA
= PR_INT32_MAX
;
100 result
.numA
= strtol(part
, const_cast<char**>(&result
.strB
), 10);
104 result
.strB
= nsnull
;
108 if (result
.strB
[0] == '+') {
109 static const char kPre
[] = "pre";
113 result
.strBlen
= sizeof(kPre
) - 1;
116 const char *numstart
= strpbrk(result
.strB
, "0123456789+-");
118 result
.strBlen
= strlen(result
.strB
);
121 result
.strBlen
= numstart
- result
.strB
;
123 result
.numC
= strtol(numstart
, &result
.extraD
, 10);
125 result
.extraD
= nsnull
;
142 * Parse a version part into a number and "extra text".
144 * @returns A pointer to the next versionpart, or null if none.
148 ParseVP(PRUnichar
*part
, VersionPartW
&result
)
154 result
.strB
= nsnull
;
157 result
.extraD
= nsnull
;
162 dot
= wcschr(part
, '.');
166 if (part
[0] == '*' && part
[1] == '\0') {
167 result
.numA
= PR_INT32_MAX
;
171 result
.numA
= wcstol(part
, const_cast<PRUnichar
**>(&result
.strB
), 10);
175 result
.strB
= nsnull
;
179 if (result
.strB
[0] == '+') {
180 static const PRUnichar kPre
[] = L
"pre";
184 result
.strBlen
= sizeof(kPre
) - 1;
187 const PRUnichar
*numstart
= wcspbrk(result
.strB
, L
"0123456789+-");
189 result
.strBlen
= wcslen(result
.strB
);
192 result
.strBlen
= numstart
- result
.strB
;
194 result
.numC
= wcstol(numstart
, &result
.extraD
, 10);
196 result
.extraD
= nsnull
;
212 // compare two null-terminated strings, which may be null pointers
214 ns_strcmp(const char *str1
, const char *str2
)
216 // any string is *before* no string
223 return strcmp(str1
, str2
);
226 // compare two length-specified string, which may be null pointers
228 ns_strnncmp(const char *str1
, PRUint32 len1
, const char *str2
, PRUint32 len2
)
230 // any string is *before* no string
237 for (; len1
&& len2
; --len1
, --len2
, ++str1
, ++str2
) {
246 return len2
== 0 ? 0 : -1;
251 // compare two PRInt32
253 ns_cmp(PRInt32 n1
, PRInt32 n2
)
262 * Compares two VersionParts
265 CompareVP(VersionPart
&v1
, VersionPart
&v2
)
267 PRInt32 r
= ns_cmp(v1
.numA
, v2
.numA
);
271 r
= ns_strnncmp(v1
.strB
, v1
.strBlen
, v2
.strB
, v2
.strBlen
);
275 r
= ns_cmp(v1
.numC
, v2
.numC
);
279 return ns_strcmp(v1
.extraD
, v2
.extraD
);
283 * Compares two VersionParts
287 CompareVP(VersionPartW
&v1
, VersionPartW
&v2
)
289 PRInt32 r
= ns_cmp(v1
.numA
, v2
.numA
);
293 r
= wcsncmp(v1
.strB
, v2
.strB
, PR_MIN(v1
.strBlen
,v2
.strBlen
));
297 r
= ns_cmp(v1
.numC
, v2
.numC
);
301 return wcscmp(v1
.extraD
, v2
.extraD
);
306 NS_CompareVersions(const PRUnichar
*A
, const PRUnichar
*B
)
308 PRUnichar
*A2
= wcsdup(A
);
312 PRUnichar
*B2
= wcsdup(B
);
319 PRUnichar
*a
= A2
, *b
= B2
;
327 result
= CompareVP(va
, vb
);
341 NS_CompareVersions(const char *A
, const char *B
)
343 char *A2
= strdup(A
);
347 char *B2
= strdup(B
);
354 char *a
= A2
, *b
= B2
;
362 result
= CompareVP(va
, vb
);