Linux x86 build fix
[LibreOffice.git] / jvmfwk / plugins / sunmajor / pluginlib / sunversion.cxx
blob667440c86ac98423e8380f33e4d449489073ad8e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "sunversion.hxx"
22 #include "osl/diagnose.h"
23 #include "osl/thread.h"
24 #include "osl/process.h"
25 #include "osl/security.hxx"
26 #include <string.h>
27 #include <ctype.h>
28 #include "diagnostics.h"
29 using namespace osl;
31 namespace jfw_plugin { //stoc_javadetect
34 #if OSL_DEBUG_LEVEL >= 2
35 class SelfTest
37 public:
38 SelfTest();
39 } test;
40 #endif
42 SunVersion::SunVersion(const OUString &usVer):
43 m_nUpdateSpecial(0), m_preRelease(Rel_NONE),
44 usVersion(usVer)
46 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
47 OString sVersion= OUStringToOString(usVer, osl_getThreadTextEncoding());
48 m_bValid = init(sVersion.getStr());
50 SunVersion::SunVersion(const char * szVer):
51 m_nUpdateSpecial(0), m_preRelease(Rel_NONE)
53 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
54 m_bValid = init(szVer);
55 usVersion= OUString(szVer,strlen(szVer),osl_getThreadTextEncoding());
59 /**Format major.minor.maintenance_update
61 bool SunVersion::init(const char *szVersion)
63 if (!szVersion || szVersion[0] == '\0')
64 return false;
66 //first get the major,minor,maintenance
67 const char * pLast = szVersion;
68 const char * pCur = szVersion;
69 //pEnd point to the position after the last character
70 const char * pEnd = szVersion + strlen(szVersion);
71 // 0 = major, 1 = minor, 2 = maintenance, 3 = update
72 int nPart = 0;
73 // position within part beginning with 0
74 int nPartPos = 0;
75 char buf[128];
77 //char must me a number 0 - 999 and no leading
78 while (true)
80 if (pCur < pEnd && isdigit(*pCur))
82 if (pCur < pEnd)
83 pCur ++;
84 nPartPos ++;
86 //if correct separator then form integer
87 else if (
88 ! (nPartPos == 0) // prevents: ".4.1", "..1", part must start with digit
89 && (
90 //separators after maintenance (1.4.1_01, 1.4.1-beta, or 1.4.1)
91 ((pCur == pEnd || *pCur == '_' || *pCur == '-') && (nPart == 2 ))
93 //separators between major-minor and minor-maintenance
94 (nPart < 2 && *pCur == '.') )
95 && (
96 //prevent 1.4.0. 1.4.0-
97 pCur + 1 != pEnd || isdigit(*(pCur))) )
99 int len = pCur - pLast;
100 if (len >= 127)
101 return false;
103 strncpy(buf, pLast, len);
104 buf[len] = 0;
105 pCur ++;
106 pLast = pCur;
108 m_arVersionParts[nPart] = atoi(buf);
109 nPart ++;
110 nPartPos = 0;
111 if (nPart == 3)
112 break;
114 //check next character
115 if (! ( (pCur < pEnd)
116 && ( (nPart < 3) && isdigit(*pCur))))
117 return false;
119 else
121 return false;
124 if (pCur >= pEnd)
125 return true;
126 //We have now 1.4.1. This can be followed by _01, -beta, etc.
127 // _01 (update) According to docu must not be followed by any other
128 //characters, but on Solaris 9 we have a 1.4.1_01a!!
129 if (* (pCur - 1) == '_')
130 {// _01, _02
131 // update is the last part _01, _01a, part 0 is the digits parts and 1 the trailing alpha
132 while (true)
134 if (pCur <= pEnd)
136 if ( ! isdigit(*pCur))
138 //1.4.1_01-, 1.4.1_01a, the numerical part may only be 2 chars.
139 int len = pCur - pLast;
140 if (len > 2)
141 return false;
142 //we've got the update: 01, 02 etc
143 strncpy(buf, pLast, len);
144 buf[len] = 0;
145 m_arVersionParts[nPart] = atoi(buf);
146 if (pCur == pEnd)
148 break;
150 if (*pCur == 'a' && (pCur + 1) == pEnd)
152 //check if it s followed by a simple "a" (not specified)
153 m_nUpdateSpecial = *pCur;
154 break;
156 else if (*pCur == '-' && pCur < pEnd)
158 //check 1.5.0_01-ea
159 PreRelease pr = getPreRelease(++pCur);
160 if (pr == Rel_NONE)
161 return false;
162 //just ignore -ea because its no official release
163 break;
165 else
167 return false;
170 if (pCur < pEnd)
171 pCur ++;
172 else
173 break;
177 // 1.4.1-ea
178 else if (*(pCur - 1) == '-')
180 m_preRelease = getPreRelease(pCur);
181 if (m_preRelease == Rel_NONE)
182 return false;
183 #if defined(FREEBSD)
184 if (m_preRelease == Rel_FreeBSD)
186 pCur++; //eliminate 'p'
187 if (pCur < pEnd && isdigit(*pCur))
188 pCur ++;
189 int len = pCur - pLast -1; //eliminate 'p'
190 if (len >= 127)
191 return false;
192 strncpy(buf, (pLast+1), len); //eliminate 'p'
193 buf[len] = 0;
194 m_nUpdateSpecial = atoi(buf)+100; //hack for FBSD #i56953#
195 return true;
197 #endif
199 else
201 return false;
203 return true;
206 SunVersion::PreRelease SunVersion::getPreRelease(const char *szRelease)
208 if (szRelease == NULL)
209 return Rel_NONE;
210 if( ! strcmp(szRelease,"internal"))
211 return Rel_INTERNAL;
212 else if( ! strcmp(szRelease,"ea"))
213 return Rel_EA;
214 else if( ! strcmp(szRelease,"ea1"))
215 return Rel_EA1;
216 else if( ! strcmp(szRelease,"ea2"))
217 return Rel_EA2;
218 else if( ! strcmp(szRelease,"ea3"))
219 return Rel_EA3;
220 else if ( ! strcmp(szRelease,"beta"))
221 return Rel_BETA;
222 else if ( ! strcmp(szRelease,"beta1"))
223 return Rel_BETA1;
224 else if ( ! strcmp(szRelease,"beta2"))
225 return Rel_BETA2;
226 else if ( ! strcmp(szRelease,"beta3"))
227 return Rel_BETA3;
228 else if (! strcmp(szRelease, "rc"))
229 return Rel_RC;
230 else if (! strcmp(szRelease, "rc1"))
231 return Rel_RC1;
232 else if (! strcmp(szRelease, "rc2"))
233 return Rel_RC2;
234 else if (! strcmp(szRelease, "rc3"))
235 return Rel_RC3;
236 #if defined (FREEBSD)
237 else if (! strncmp(szRelease, "p", 1))
238 return Rel_FreeBSD;
239 #endif
240 else
241 return Rel_NONE;
244 SunVersion::~SunVersion()
249 /* Examples:
250 a) 1.0 < 1.1
251 b) 1.0 < 1.0.0
252 c) 1.0 < 1.0_00
254 returns false if both values are equal
256 bool SunVersion::operator > (const SunVersion& ver) const
258 if( &ver == this)
259 return false;
261 //compare major.minor.maintenance
262 for( int i= 0; i < 4; i ++)
264 // 1.4 > 1.3
265 if(m_arVersionParts[i] > ver.m_arVersionParts[i])
267 return true;
269 else if (m_arVersionParts[i] < ver.m_arVersionParts[i])
271 return false;
274 //major.minor.maintenance_update are equal. Test for a trailing char
275 if (m_nUpdateSpecial > ver.m_nUpdateSpecial)
277 return true;
280 //Until here the versions are equal
281 //compare pre -release values
282 if ((m_preRelease == Rel_NONE && ver.m_preRelease == Rel_NONE)
284 (m_preRelease != Rel_NONE && ver.m_preRelease == Rel_NONE))
285 return false;
286 else if (m_preRelease == Rel_NONE && ver.m_preRelease != Rel_NONE)
287 return true;
288 else if (m_preRelease > ver.m_preRelease)
289 return true;
291 return false;
294 bool SunVersion::operator < (const SunVersion& ver) const
296 return (! operator > (ver)) && (! operator == (ver));
299 bool SunVersion::operator == (const SunVersion& ver) const
301 bool bRet= true;
302 for(int i= 0; i < 4; i++)
304 if( m_arVersionParts[i] != ver.m_arVersionParts[i])
306 bRet= false;
307 break;
310 bRet = m_nUpdateSpecial == ver.m_nUpdateSpecial && bRet;
311 bRet = m_preRelease == ver.m_preRelease && bRet;
312 return bRet;
316 #if OSL_DEBUG_LEVEL >= 2
317 SelfTest::SelfTest()
319 bool bRet = true;
321 char const * versions[] = {"1.4.0", "1.4.1", "1.0.0", "10.0.0", "10.10.0",
322 "10.2.2", "10.10.0", "10.10.10", "111.0.999",
323 "1.4.1_01", "9.90.99_09", "1.4.1_99",
324 "1.4.1_00a",
325 "1.4.1-ea", "1.4.1-beta", "1.4.1-rc1",
326 "1.5.0_01-ea", "1.5.0_01-rc2"};
327 char const * badVersions[] = {".4.0", "..1", "", "10.0", "10.10.0.", "10.10.0-", "10.10.0.",
328 "10.2-2", "10_10.0", "10..10","10.10", "a.0.999",
329 "1.4b.1_01", "9.90.-99_09", "1.4.1_99-",
330 "1.4.1_00a2", "1.4.0_z01z", "1.4.1__99A",
331 "1.4.1-1ea", "1.5.0_010", "1.5.0._01-", "1.5.0_01-eac"};
332 char const * orderedVer[] = { "1.3.1-ea", "1.3.1-beta", "1.3.1-rc1",
333 "1.3.1", "1.3.1_00a", "1.3.1_01", "1.3.1_01a",
334 "1.3.2", "1.4.0", "1.5.0_01-ea", "2.0.0"};
336 int num = sizeof (versions) / sizeof(char*);
337 int numBad = sizeof (badVersions) / sizeof(char*);
338 int numOrdered = sizeof (orderedVer) / sizeof(char*);
339 //parsing test (positive)
340 for (int i = 0; i < num; i++)
342 SunVersion ver(versions[i]);
343 if ( ! ver)
345 bRet = false;
346 break;
349 OSL_ENSURE(bRet, "SunVersion selftest failed");
350 //Parsing test (negative)
351 for ( int i = 0; i < numBad; i++)
353 SunVersion ver(badVersions[i]);
354 if (ver)
356 bRet = false;
357 break;
360 OSL_ENSURE(bRet, "SunVersion selftest failed");
362 // Ordering test
363 bRet = true;
364 int j = 0;
365 for (int i = 0; i < numOrdered; i ++)
367 SunVersion curVer(orderedVer[i]);
368 if ( ! curVer)
370 bRet = false;
371 break;
373 for (j = 0; j < numOrdered; j++)
375 SunVersion compVer(orderedVer[j]);
376 if (i < j)
378 if ( !(curVer < compVer))
380 bRet = false;
381 break;
384 else if ( i == j)
386 if (! (curVer == compVer
387 && ! (curVer > compVer)
388 && ! (curVer < compVer)))
390 bRet = false;
391 break;
394 else if (i > j)
396 if ( !(curVer > compVer))
398 bRet = false;
399 break;
403 if ( ! bRet)
404 break;
406 if (bRet)
407 JFW_TRACE2("Testing class SunVersion succeeded.");
408 else
409 OSL_ENSURE(bRet, "[Java framework] sunjavaplugin: SunVersion self test failed.\n");
411 #endif
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */