src/corelib/global/qglobal.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
--- a/src/corelib/global/qglobal.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/corelib/global/qglobal.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -78,6 +78,7 @@
 #include <e32debug.h>
 #include <flogger.h>
 #include <f32file.h>
+#include <e32math.h>
 # include "private/qcore_symbian_p.h"
 _LIT(qt_S60Filter, "Series60v?.*.sis");
 _LIT(qt_S60SystemInstallDir, "z:\\system\\install\\");
@@ -961,7 +962,7 @@
     \relates <QtGlobal>
 
     Turns the major, minor and patch numbers of a version into an
-    integer, 0xMMNNPP (MM = major, NN = minor, PP = patch). This can 
+    integer, 0xMMNNPP (MM = major, NN = minor, PP = patch). This can
     be compared with another similarly processed version id.
 
     \sa QT_VERSION
@@ -1192,6 +1193,10 @@
     \value SV_9_2 Symbian OS v9.2
     \value SV_9_3 Symbian OS v9.3
     \value SV_9_4 Symbian OS v9.4
+    \value SV_SF_1 Symbian^1
+    \value SV_SF_2 Symbian^2
+    \value SV_SF_3 Symbian^3
+    \value SV_SF_4 Symbian^4
     \value SV_Unknown An unknown and currently unsupported platform
 
     \sa S60Version, WinVersion, MacVersion
@@ -1208,6 +1213,8 @@
     \value SV_S60_3_1 S60 3rd Edition Feature Pack 1
     \value SV_S60_3_2 S60 3rd Edition Feature Pack 2
     \value SV_S60_5_0 S60 5th Edition
+    \value SV_S60_5_1 S60 5th Edition Feature Pack 1
+    \value SV_S60_5_2 S60 5th Edition Feature Pack 2
     \value SV_S60_Unknown An unknown and currently unsupported platform
     \omitvalue SV_S60_None
 
@@ -1796,7 +1803,7 @@
     TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_S60SystemInstallDir, contents);
     if (err == KErrNone) {
         err = contents->Sort(EDescending|ESortByName);
-        if (err == KErrNone) {
+        if (err == KErrNone && contents->Count() > 0 && (*contents)[0].iName.Length() >= 12) {
             TInt major = (*contents)[0].iName[9] - '0';
             TInt minor = (*contents)[0].iName[11] - '0';
             if (major == 3) {
@@ -1809,6 +1816,12 @@
                 if (minor == 0) {
                     return cachedS60Version = SV_S60_5_0;
                 }
+                else if (minor == 1) {
+                    return cachedS60Version = SV_S60_5_1;
+                }
+                else if (minor == 2) {
+                    return cachedS60Version = SV_S60_5_2;
+                }
             }
         }
         delete contents;
@@ -1823,12 +1836,10 @@
     return cachedS60Version = SV_S60_3_2;
 #   elif defined(__S60_50__)
     return cachedS60Version = SV_S60_5_0;
-#   else
+#   endif
+#  endif
+    //If reaching here, it was not possible to determine the version
     return cachedS60Version = SV_S60_Unknown;
-#   endif
-#  else
-    return cachedS60Version = SV_S60_Unknown;
-#  endif
 }
 QSysInfo::SymbianVersion QSysInfo::symbianVersion()
 {
@@ -1839,6 +1850,10 @@
         return SV_9_3;
     case SV_S60_5_0:
         return SV_9_4;
+    case SV_S60_5_1:
+        return SV_9_4;
+    case SV_S60_5_2:
+        return SV_9_4;
     default:
         return SV_Unknown;
     }
@@ -2165,24 +2180,28 @@
         fstr += QLatin1Char('\n');
         OutputDebugString(reinterpret_cast<const wchar_t *> (fstr.utf16()));
 #elif defined(Q_OS_SYMBIAN)
+        // RDebug::Print has a cap of 256 characters so break it up
         _LIT(format, "[Qt Message] %S");
+        const int maxBlockSize = 256 - ((const TDesC &)format).Length();
         const TPtrC8 ptr(reinterpret_cast<const TUint8*>(buf));
-#if !defined(QT_WARNING_FILE_OUTPUT)        
-        // RDebug::Print has a cap of 256 characters so break it up
-        const int maxBlockSize = 256 - ((const TDesC &)format).Length();
         HBufC* hbuffer = q_check_ptr(HBufC::New(qMin(maxBlockSize, ptr.Length())));
         for (int i = 0; i < ptr.Length(); i += hbuffer->Length()) {
             hbuffer->Des().Copy(ptr.Mid(i, qMin(maxBlockSize, ptr.Length()-i)));
             RDebug::Print(format, hbuffer);
         }
         delete hbuffer;
-#else
+//QTP:Prod add logging to the file
+#if defined(QT_WARNING_FILE_OUTPUT)
         _LIT( KLogDir, "QT" );
         _LIT( KLogFile, "QT.log" );
-        _LIT( KLogStarting, "*** Starting new Qt application ***");
+        _LIT( KLogStarting, "Starting: %S");
         static bool logStarted;
         if ( !logStarted ){
-            RFileLogger::Write( KLogDir, KLogFile, EFileLoggingModeAppend, KLogStarting );        
+            RProcess curProc;
+            TBuf<KMaxFullName + 20> procName;
+            TFullName fullName = curProc.FullName();
+            procName.Format(KLogStarting, &fullName);
+            RFileLogger::Write( KLogDir, KLogFile, EFileLoggingModeAppend, procName);
             logStarted = true; 
         }
 
@@ -2493,7 +2512,7 @@
 #endif
 }
 
-#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
+#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
 
 #  if defined(Q_OS_INTEGRITY) && defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 500)
 // older versions of INTEGRITY used a long instead of a uint for the seed.
@@ -2516,8 +2535,6 @@
     Sets the argument \a seed to be used to generate a new random number sequence of
     pseudo random integers to be returned by qrand().
 
-    If no seed value is provided, qrand() is automatically seeded with a value of 1.
-
     The sequence of random numbers generated is deterministic per thread. For example,
     if two threads call qsrand(1) and subsequently calls qrand(), the threads will get
     the same random number sequence.
@@ -2527,13 +2544,23 @@
 void qsrand(uint seed)
 {
 #if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
-    SeedStorageType *pseed = randTLS()->localData();
-    if (!pseed)
-        randTLS()->setLocalData(pseed = new SeedStorageType);
-    *pseed = seed;
+    SeedStorage *seedStorage = randTLS();
+    if (seedStorage) {
+        SeedStorageType *pseed = seedStorage->localData();
+        if (!pseed)
+            seedStorage->setLocalData(pseed = new SeedStorageType);
+        *pseed = seed;
+    } else {
+        //golbal static seed storage should always exist,
+        //except after being deleted by QGlobalStaticDeleter.
+        //But since it still can be called from destructor of another
+        //global static object, fallback to sqrand(seed)
+        srand(seed);
+    }
 #else
-    // On Windows srand() and rand() already use Thread-Local-Storage
+    // On Windows and Symbian srand() and rand() already use Thread-Local-Storage
     // to store the seed between calls
+    // this is also valid for QT_NO_THREAD
     srand(seed);
 #endif
 }
@@ -2549,35 +2576,42 @@
 */
 void qsrand()
 {
-#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
-    SeedStorageType *pseed = randTLS()->localData();
-    if (pseed) {
-        // already seeded
-        return;
+#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
+    SeedStorage *seedStorage = randTLS();
+    if (seedStorage) {
+        SeedStorageType *pseed = seedStorage->localData();
+        if (pseed) {
+            // already seeded
+            return;
+        }
+        seedStorage->setLocalData(pseed = new SeedStorageType);
+        // start beyond 1 to avoid the sequence reset
+        static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
+        *pseed = QDateTime::currentDateTime().toTime_t()
+                 + quintptr(&pseed)
+                 + serial.fetchAndAddRelaxed(1);
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+        // for Windows and Symbian the srand function must still be called.
+        srand(*pseed);
+#endif
     }
-    randTLS()->setLocalData(pseed = new SeedStorageType);
-    // start beyond 1 to avoid the sequence reset
-    static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
-    *pseed = QDateTime::currentDateTime().toTime_t()
-             + quintptr(&pseed)
-             + serial.fetchAndAddRelaxed(1);
-#if defined(Q_OS_WIN)
-    // for Windows the srand function must still be called.
-    srand(*pseed);
-#endif
-
-#elif defined(Q_OS_WIN)
+
+//QT_NO_THREAD implementations
+#else
     static unsigned int seed = 0;
 
     if (seed)
         return;
 
+#if defined(Q_OS_SYMBIAN)
+    seed = Math::Random();
+#elif defined(Q_OS_WIN)
     seed = GetTickCount();
+#else
+    seed = quintptr(&seed) + QDateTime::currentDateTime().toTime_t();
+#endif
     srand(seed);
-#else 
-    // Symbian?
-
-#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
+#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
 }
 
 /*!
@@ -2598,15 +2632,25 @@
 int qrand()
 {
 #if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
-    SeedStorageType *pseed = randTLS()->localData();
-    if (!pseed) {
-        randTLS()->setLocalData(pseed = new SeedStorageType);
-        *pseed = 1;
+    SeedStorage *seedStorage = randTLS();
+    if (seedStorage) {
+        SeedStorageType *pseed = seedStorage->localData();
+        if (!pseed) {
+            seedStorage->setLocalData(pseed = new SeedStorageType);
+            *pseed = 1;
+        }
+        return rand_r(pseed);
+    } else {
+        //golbal static seed storage should always exist,
+        //except after being deleted by QGlobalStaticDeleter.
+        //But since it still can be called from destructor of another
+        //global static object, fallback to qrand()
+        return rand();
     }
-    return rand_r(pseed);
 #else
-    // On Windows srand() and rand() already use Thread-Local-Storage
+    // On Windows and Symbian srand() and rand() already use Thread-Local-Storage
     // to store the seed between calls
+    // this is also valid for QT_NO_THREAD
     return rand();
 #endif
 }