Update ooo320-m1
[ooovba.git] / jvmfwk / plugins / sunmajor / pluginlib / sunversion.cxx
blobae0b76b4a93b26c719d47b720bd7ded95479433a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sunversion.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_jvmfwk.hxx"
34 #include "sunversion.hxx"
35 #include "osl/thread.h"
36 #include "osl/process.h"
37 #include "osl/security.hxx"
38 #include <string.h>
39 #include <ctype.h>
40 #include "diagnostics.h"
41 using namespace rtl;
42 using namespace osl;
43 namespace jfw_plugin { //stoc_javadetect
46 //extern OUString ::Impl::usPathDelim();
47 #define OUSTR( x ) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
49 #if OSL_DEBUG_LEVEL >= 2
50 class SelfTest
52 public:
53 SelfTest();
54 } test;
55 #endif
57 SunVersion::SunVersion(): m_nUpdateSpecial(0),
58 m_preRelease(Rel_NONE),
59 m_bValid(false)
61 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
64 SunVersion::SunVersion(const rtl::OUString &usVer):
65 m_nUpdateSpecial(0), m_preRelease(Rel_NONE),
66 usVersion(usVer)
68 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
69 rtl::OString sVersion= rtl::OUStringToOString(usVer, osl_getThreadTextEncoding());
70 m_bValid = init(sVersion.getStr());
72 SunVersion::SunVersion(const char * szVer):
73 m_nUpdateSpecial(0), m_preRelease(Rel_NONE)
75 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
76 m_bValid = init(szVer);
77 usVersion= rtl::OUString(szVer,strlen(szVer),osl_getThreadTextEncoding());
81 /**Format major.minor.maintainance_update
83 bool SunVersion::init(const char *szVersion)
85 if ( ! szVersion || strlen(szVersion) == 0)
86 return false;
88 //first get the major,minor,maintainance
89 const char * pLast = szVersion;
90 const char * pCur = szVersion;
91 //pEnd point to the position after the last character
92 const char * pEnd = szVersion + strlen(szVersion);
93 // 0 = major, 1 = minor, 2 = maintainance, 3 = update
94 int nPart = 0;
95 // position within part beginning with 0
96 int nPartPos = 0;
97 char buf[128];
99 //char must me a number 0 - 999 and no leading
100 while (1)
102 if (pCur < pEnd && isdigit(*pCur))
104 if (pCur < pEnd)
105 pCur ++;
106 nPartPos ++;
108 //if correct separator then form integer
109 else if (
110 ! (nPartPos == 0) // prevents: ".4.1", "..1", part must start with digit
111 && (
112 //seperators after maintainance (1.4.1_01, 1.4.1-beta, or1.4.1
113 ((pCur == pEnd || *pCur == '_' || *pCur == '-') && (nPart == 2 ))
115 //separators between major-minor and minor-maintainance
116 (nPart < 2 && *pCur == '.') )
117 && (
118 //prevent 1.4.0. 1.4.0-
119 pCur + 1 == pEnd ? isdigit(*(pCur)) : 1) )
121 int len = pCur - pLast;
122 if (len >= 127)
123 return false;
125 strncpy(buf, pLast, len);
126 buf[len] = 0;
127 pCur ++;
128 pLast = pCur;
130 m_arVersionParts[nPart] = atoi(buf);
131 nPart ++;
132 nPartPos = 0;
133 if (nPart == 3)
134 break;
136 //check next character
137 if (! ( (pCur < pEnd)
138 && ( (nPart < 3) && isdigit(*pCur)))) //(*pCur >= 48 && *pCur <=57))))
139 return false;
141 else
143 return false;
146 if (pCur >= pEnd)
147 return true;
148 //We have now 1.4.1. This can be followed by _01, -beta, etc.
149 // _01 (update) According to docu must not be followed by any other
150 //characters, but on Solaris 9 we have a 1.4.1_01a!!
151 if (* (pCur - 1) == '_')
152 {// _01, _02
153 // update is the last part _01, _01a, part 0 is the digits parts and 1 the trailing alpha
154 while (1)
156 if (pCur <= pEnd)
158 if ( ! isdigit(*pCur))
160 //1.4.1_01-, 1.4.1_01a, the numerical part may only be 2 chars.
161 int len = pCur - pLast;
162 if (len > 2)
163 return false;
164 //we've got the update: 01, 02 etc
165 strncpy(buf, pLast, len);
166 buf[len] = 0;
167 m_arVersionParts[nPart] = atoi(buf);
168 if (pCur == pEnd)
170 break;
172 if (*pCur == 'a' && (pCur + 1) == pEnd)
174 //check if it s followed by a simple "a" (not specified)
175 m_nUpdateSpecial = *pCur;
176 break;
178 else if (*pCur == '-' && pCur < pEnd)
180 //check 1.5.0_01-ea
181 PreRelease pr = getPreRelease(++pCur);
182 if (pr == Rel_NONE)
183 return false;
184 //just ignore -ea because its no official release
185 break;
187 else
189 return false;
192 if (pCur < pEnd)
193 pCur ++;
194 else
195 break;
199 // 1.4.1-ea
200 else if (*(pCur - 1) == '-')
202 m_preRelease = getPreRelease(pCur);
203 if (m_preRelease == Rel_NONE)
204 return false;
205 #if defined(FREEBSD)
206 if (m_preRelease == Rel_FreeBSD)
208 pCur++; //elemnate `p'
209 if (pCur < pEnd && isdigit(*pCur))
210 pCur ++;
211 int len = pCur - pLast -1; //elemenate `p'
212 if (len >= 127)
213 return false;
214 strncpy(buf, (pLast+1), len); //elemenate `p'
215 buf[len] = 0;
216 m_nUpdateSpecial = atoi(buf)+100; //hack for FBSD #i56953#
217 return true;
219 #endif
221 else
223 return false;
225 return true;
228 SunVersion::PreRelease SunVersion::getPreRelease(const char *szRelease)
230 if (szRelease == NULL)
231 return Rel_NONE;
232 if( ! strcmp(szRelease,"ea"))
233 return Rel_EA;
234 else if( ! strcmp(szRelease,"ea1"))
235 return Rel_EA1;
236 else if( ! strcmp(szRelease,"ea2"))
237 return Rel_EA2;
238 else if( ! strcmp(szRelease,"ea3"))
239 return Rel_EA3;
240 else if ( ! strcmp(szRelease,"beta"))
241 return Rel_BETA;
242 else if ( ! strcmp(szRelease,"beta1"))
243 return Rel_BETA1;
244 else if ( ! strcmp(szRelease,"beta2"))
245 return Rel_BETA2;
246 else if ( ! strcmp(szRelease,"beta3"))
247 return Rel_BETA3;
248 else if (! strcmp(szRelease, "rc"))
249 return Rel_RC;
250 else if (! strcmp(szRelease, "rc1"))
251 return Rel_RC1;
252 else if (! strcmp(szRelease, "rc2"))
253 return Rel_RC2;
254 else if (! strcmp(szRelease, "rc3"))
255 return Rel_RC3;
256 #if defined (FREEBSD)
257 else if (! strncmp(szRelease, "p", 1))
258 return Rel_FreeBSD;
259 #endif
260 else
261 return Rel_NONE;
264 SunVersion::~SunVersion()
269 /* Examples:
270 a) 1.0 < 1.1
271 b) 1.0 < 1.0.0
272 c) 1.0 < 1.0_00
274 returns false if both values are equal
276 bool SunVersion::operator > (const SunVersion& ver) const
278 if( &ver == this)
279 return false;
281 //compare major.minor.maintainance
282 for( int i= 0; i < 4; i ++)
284 // 1.4 > 1.3
285 if(m_arVersionParts[i] > ver.m_arVersionParts[i])
287 return true;
289 else if (m_arVersionParts[i] < ver.m_arVersionParts[i])
291 return false;
294 //major.minor.maintainance_update are equal. test for a trailing char
295 if (m_nUpdateSpecial > ver.m_nUpdateSpecial)
297 return true;
300 //Until here the versions are equal
301 //compare pre -release values
302 if ((m_preRelease == Rel_NONE && ver.m_preRelease == Rel_NONE)
304 (m_preRelease != Rel_NONE && ver.m_preRelease == Rel_NONE))
305 return false;
306 else if (m_preRelease == Rel_NONE && ver.m_preRelease != Rel_NONE)
307 return true;
308 else if (m_preRelease > ver.m_preRelease)
309 return true;
311 return false;
314 bool SunVersion::operator < (const SunVersion& ver) const
316 return (! operator > (ver)) && (! operator == (ver));
319 bool SunVersion::operator == (const SunVersion& ver) const
321 bool bRet= true;
322 for(int i= 0; i < 4; i++)
324 if( m_arVersionParts[i] != ver.m_arVersionParts[i])
326 bRet= false;
327 break;
330 bRet = m_nUpdateSpecial == ver.m_nUpdateSpecial && bRet;
331 bRet = m_preRelease == ver.m_preRelease && bRet;
332 return bRet;
335 SunVersion::operator bool()
337 return m_bValid;
340 #if OSL_DEBUG_LEVEL >= 2
341 SelfTest::SelfTest()
343 bool bRet = true;
345 char const * versions[] = {"1.4.0", "1.4.1", "1.0.0", "10.0.0", "10.10.0",
346 "10.2.2", "10.10.0", "10.10.10", "111.0.999",
347 "1.4.1_01", "9.90.99_09", "1.4.1_99",
348 "1.4.1_00a",
349 "1.4.1-ea", "1.4.1-beta", "1.4.1-rc1",
350 "1.5.0_01-ea", "1.5.0_01-rc2"};
351 char const * badVersions[] = {".4.0", "..1", "", "10.0", "10.10.0.", "10.10.0-", "10.10.0.",
352 "10.2-2", "10_10.0", "10..10","10.10", "a.0.999",
353 "1.4b.1_01", "9.90.-99_09", "1.4.1_99-",
354 "1.4.1_00a2", "1.4.0_z01z", "1.4.1__99A",
355 "1.4.1-1ea", "1.5.0_010", "1.5.0._01-", "1.5.0_01-eac"};
356 char const * orderedVer[] = { "1.3.1-ea", "1.3.1-beta", "1.3.1-rc1",
357 "1.3.1", "1.3.1_00a", "1.3.1_01", "1.3.1_01a",
358 "1.3.2", "1.4.0", "1.5.0_01-ea", "2.0.0"};
360 int num = sizeof (versions) / sizeof(char*);
361 int numBad = sizeof (badVersions) / sizeof(char*);
362 int numOrdered = sizeof (orderedVer) / sizeof(char*);
363 //parsing test (positive)
364 for (int i = 0; i < num; i++)
366 SunVersion ver(versions[i]);
367 if ( ! ver)
369 bRet = false;
370 break;
373 OSL_ENSURE(bRet, "SunVersion selftest failed");
374 //Parsing test (negative)
375 for ( int i = 0; i < numBad; i++)
377 SunVersion ver(badVersions[i]);
378 if (ver)
380 bRet = false;
381 break;
384 OSL_ENSURE(bRet, "SunVersion selftest failed");
386 // Ordering test
387 bRet = true;
388 int j = 0;
389 for (int i = 0; i < numOrdered; i ++)
391 SunVersion curVer(orderedVer[i]);
392 if ( ! curVer)
394 bRet = false;
395 break;
397 for (j = 0; j < numOrdered; j++)
399 SunVersion compVer(orderedVer[j]);
400 if (i < j)
402 if ( !(curVer < compVer))
404 bRet = false;
405 break;
408 else if ( i == j)
410 if (! (curVer == compVer
411 && ! (curVer > compVer)
412 && ! (curVer < compVer)))
414 bRet = false;
415 break;
418 else if (i > j)
420 if ( !(curVer > compVer))
422 bRet = false;
423 break;
427 if ( ! bRet)
428 break;
430 if (bRet)
431 JFW_TRACE2("[Java framework] sunjavaplugin: Testing class SunVersion succeeded.");
432 else
433 OSL_ENSURE(bRet, "[Java framework] sunjavaplugin: SunVersion self test failed");
435 #endif