Liviu Nicoara wrote:

Thanks! (In the future, please make sure to explain what the patch
does in case it's not obvious to everyone).

Here's the output of the test I get on Windows 2000 Professional:

   #define _RWSTD_OS_WINDOWS
   #define _RWSTD_OS_SYSNAME "WINDOWS"
   #define _RWSTD_OS_RELEASE "5.0"
   #define _RWSTD_OS_MAJOR 5
   #define _RWSTD_OS_MINOR 0
   #undef _RWSTD_OS_VERSION
   #undef _RWSTD_OS_MICRO

Index: etc/config/src/UNAME.cpp
===================================================================
--- etc/config/src/UNAME.cpp    (revision 219737)
+++ etc/config/src/UNAME.cpp    (working copy)
@@ -103,8 +103,27 @@

 #else

-    return 1;
+    OSVERSIONINFO osinfo;
+    osinfo.dwOSVersionInfoSize = sizeof osinfo;

+    if (!::GetVersionEx (&osinfo))

(FYI: there's no reason to qualify the call above.)

+        return 1;
+
+    printf ("#define _RWSTD_OS_WINDOWS\n");
+    printf ("#define _RWSTD_OS_SYSNAME \"WINDOWS\"\n");

I would suggest to #define these two unconditionally (i.e., regardless
of whether GetVersion() succeeds or not), and probably also to avoid
returning a non-0 status on GetVersion() failure.

+
+    // no micro on Windows
+    printf ("#define _RWSTD_OS_RELEASE \"%d.%d\"\n",
+            osinfo.dwMajorVersion,
+            osinfo.dwMinorVersion);

I think this macro would be more useful if it identified the flavor
of Windows, i.e., one of "2000", "NT 4.0", "95", "XP", "Server 2003",
"98", or "Me". It should be possible to extract it (or most of it)
from dwMajorVersion, dwMinorVersion, and dwPlatformId:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/osversioninfo_str.asp

+
+    printf ("#define _RWSTD_OS_MAJOR %lu\n", osinfo.dwMajorVersion);
+    printf ("#define _RWSTD_OS_MINOR %lu\n", osinfo.dwMinorVersion);

Hmmm. These are supposed to let us easily identify the version in
preprocessor conditionals. Let's see, what would the values for
the different flavors of Windows look like?

      Windows   _RWSTD_OS_MAJOR _RWSTD_OS_MINOR
   +-----------+---------------+---------------+
   |    95     |       4       |       0 (*)   |
   |    98     |       4       |      10       |
   |    Me     |       4       |      90       |
   |  NT 4.0   |       4       |       0 (*)   |
   |   2000    |       5       |       0       |
   |Server 2003|       5       |       2       |
   |    XP     |       5       |       1       |
   +-----------+---------------+---------------+

Okay, that's not too bad, except that the special case (*) would
have to be handled. It might be useful to also #define a helper
macro corresponding to each flavor of Windows:

     _RWSTD_OS_WINDOWS_95
     _RWSTD_OS_WINDOWS_98
     _RWSTD_OS_WINDOWS_ME
     _RWSTD_OS_WINDOWS_NT
     _RWSTD_OS_WINDOWS_2000
     _RWSTD_OS_WINDOWS_2003
     _RWSTD_OS_WINDOWS_XP

+
+    // not applicable
+    printf ("#undef _RWSTD_OS_VERSION\n");
+    printf ("#undef _RWSTD_OS_MICRO\n");

These tests shouldn't #undefine any config macros. If it's not
applicable, the _RWSTD_OS_MICRO should be #defined to 0, although
it might be meaningful to define to the Windows build number
(dwBuildNumber, or its low word on 95/98/Me). _RWSTD_OS_VERSION
could be #defined to szCSDVersion.

Attached is a modified version of the patch with the changes
mentioned above. It produces the following output on the same
Windows 2000 box:

    #define _RWSTD_OS_WINDOWS
    #define _RWSTD_OS_SYSNAME "WINDOWS"
    #define _RWSTD_OS_MAJOR 5
    #define _RWSTD_OS_MINOR 0
    #define _RWSTD_OS_MICRO 2195 /* build number */
    #define _RWSTD_OS_RELEASE "Windows 2000"
    #define _RWSTD_OS_WINDOWS_2000
    #define _RWSTD_OS_VERSION "Service Pack 4"

Martin
Index: stdcxx/etc/config/src/UNAME.cpp
===================================================================
--- stdcxx/etc/config/src/UNAME.cpp     (revision 219823)
+++ stdcxx/etc/config/src/UNAME.cpp     (working copy)
@@ -69,6 +69,10 @@
     const char *s;
     unsigned long num;
 
+#if !defined (SYS_NMLN)
+#  define SYS_NMLN   128
+#endif   // SYS_NMLN
+
     char str [SYS_NMLN * 2];
 
     for (num = 0; (str [num] = uts.release [num]); ++num);
@@ -101,11 +105,58 @@
 
     printf ("#define _RWSTD_OS_MICRO %lu\n", num);
 
-#else
+#else   // if defined (_WIN{32,64})
 
-    return 1;
+    OSVERSIONINFO osinfo;
+    osinfo.dwOSVersionInfoSize = sizeof osinfo;
 
-#endif
+    const BOOL success = GetVersionEx (&osinfo);
 
+    printf ("#define _RWSTD_OS_WINDOWS\n");
+    printf ("#define _RWSTD_OS_SYSNAME \"WINDOWS\"\n");
+
+    if (!success)
+        return 0;
+
+    printf ("#define _RWSTD_OS_MAJOR %lu\n", osinfo.dwMajorVersion);
+    printf ("#define _RWSTD_OS_MINOR %lu\n", osinfo.dwMinorVersion);
+    printf ("#define _RWSTD_OS_MICRO %lu /* build number */\n",
+            osinfo.dwBuildNumber);
+
+    const char *flavor = 0;
+
+    if (4 == osinfo.dwMajorVersion) {
+        switch (osinfo.dwMinorVersion) {
+        case 0:
+            if (VER_PLATFORM_WIN32_NT == osinfo.dwPlatformId)
+                flavor = "NT";
+            else
+                flavor = "95";
+            break;
+                
+        case 10: flavor = "98"; break;
+        case 90: flavor = "ME"; break;
+        }
+    }
+    else if (5 == osinfo.dwMajorVersion) {
+        switch (osinfo.dwMinorVersion) {
+        case 0: flavor = "2000"; break;
+        case 1: flavor = "XP"; break;
+        case 2: flavor = "2003"; break;
+        }
+    }
+
+    if (flavor) {
+        printf ("#define _RWSTD_OS_RELEASE \"Windows %s\"\n", flavor);
+        printf ("#define _RWSTD_OS_WINDOWS_%s\n", flavor);
+    }
+    else {
+        printf ("#define _RWSTD_OS_RELEASE \"\"\n");
+    }
+
+    printf ("#define _RWSTD_OS_VERSION \"%s\"\n", osinfo.szCSDVersion);
+
+#endif   // _WIN{32,64}
+
     return 0;
 }

Reply via email to