1ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#!/usr/bin/env python
2ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
3ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh""" This module tries to retrieve as much platform-identifying data as
4ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    possible. It makes this information available via function APIs.
5ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
6ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    If called from the command line, it prints the platform
7ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    information concatenated as single string to stdout. The output
8ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    format is useable as part of a filename.
9ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
10ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh"""
11ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    This module is maintained by Marc-Andre Lemburg <mal@egenix.com>.
12ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    If you find problems, please submit bug reports/patches via the
13ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    Python bug tracker (http://bugs.python.org) and assign them to "lemburg".
14ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
15ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    Note: Please keep this module compatible to Python 1.5.2.
16ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
17ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    Still needed:
18ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    * more support for WinCE
19ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    * support for MS-DOS (PythonDX ?)
20ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    * support for Amiga and other still unsupported platforms running Python
21ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    * support for additional Linux distributions
22ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
23ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    Many thanks to all those who helped adding platform-specific
24ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    checks (in no particular order):
25ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
26ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
27ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
28ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
29ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
30ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
31ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#      Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter
32ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
33ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    History:
34ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
35ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    <see CVS and SVN checkin messages for history>
36ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
37ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.7 - added DEV_NULL
38ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.6 - added linux_distribution()
39ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.5 - fixed Java support to allow running the module on Jython
40ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.4 - added IronPython support
41ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.3 - added normalization of Windows system name
42ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.2 - added more Windows support
43ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.1 - reformatted to make doc.py happy
44ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    1.0.0 - reformatted a bit and checked into Python CVS
45ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.8.0 - added sys.version parser and various new access
46ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            APIs (python_version(), python_compiler(), etc.)
47ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
48ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.7.1 - added support for Caldera OpenLinux
49ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.7.0 - some fixes for WinCE; untabified the source file
50ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
51ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            vms_lib.getsyi() configured
52ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.6.1 - added code to prevent 'uname -p' on platforms which are
53ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            known not to support it
54ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
55ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            did some cleanup of the interfaces - some APIs have changed
56ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.5 - fixed another type in the MacOS code... should have
57ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            used more coffee today ;-)
58ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.4 - fixed a few typos in the MacOS code
59ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.3 - added experimental MacOS support; added better popen()
60ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            workarounds in _syscmd_ver() -- still not 100% elegant
61ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            though
62ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
63ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            return values (the system uname command tends to return
64ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            'unknown' instead of just leaving the field emtpy)
65ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.1 - included code for slackware dist; added exception handlers
66ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            to cover up situations where platforms don't have os.popen
67ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
68ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            detection RE
69ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.5.0 - changed the API names referring to system commands to *syscmd*;
70ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            added java_ver(); made syscmd_ver() a private
71ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            API (was system_ver() in previous versions) -- use uname()
72ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            instead; extended the win32_ver() to also return processor
73ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            type information
74ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
75ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.3.4 - fixed a bug in _follow_symlinks()
76ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.3.3 - fixed popen() and "file" command invokation bugs
77ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.3.2 - added architecture() API and support for it in platform()
78ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
79ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.3.0 - added system alias support
80ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.2.3 - removed 'wince' again... oh well.
81ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
82ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.2.1 - added cache logic and changed the platform string format
83ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.2.0 - changed the API to use functions instead of module globals
84ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#            since some action take too long to be run on module import
85ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    0.1.0 - first release
86ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
87ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    You can always get the latest version of this module at:
88ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
89ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#             http://www.egenix.com/files/python/platform.py
90ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
91ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#    If that URL should fail, try contacting the author.
92ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
93ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh__copyright__ = """
94ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
95ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com
96ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
97ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    Permission to use, copy, modify, and distribute this software and its
98ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    documentation for any purpose and without fee or royalty is hereby granted,
99ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    provided that the above copyright notice appear in all copies and that
100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    both that copyright notice and this permission notice appear in
101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    supporting documentation or portions thereof, including modifications,
102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    that you make.
103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh"""
113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh__version__ = '1.0.7'
115ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
116ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport sys,string,os,re
117ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
118ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Globals & Constants
119ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
120ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Determine the platform's /dev/null device
121ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehtry:
122ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    DEV_NULL = os.devnull
123ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehexcept AttributeError:
124ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # os.devnull was added in Python 2.4, so emulate it for earlier
125ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Python versions
126ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
127ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Use the old CP/M NUL as device name
128ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        DEV_NULL = 'NUL'
129ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
130ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Standard Unix uses /dev/null
131ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        DEV_NULL = '/dev/null'
132ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
133ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Platform specific APIs
134ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
135ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_libc_search = re.compile(r'(__libc_init)'
136ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                          '|'
137ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                          '(GLIBC_([0-9.]+))'
138ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                          '|'
139ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                          '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)')
140ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
141ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef libc_ver(executable=sys.executable,lib='',version='',
142ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
143ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh             chunksize=2048):
144ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
145ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Tries to determine the libc version that the file executable
146ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        (which defaults to the Python interpreter) is linked against.
147ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
148ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Returns a tuple of strings (lib,version) which default to the
149ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        given parameters in case the lookup fails.
150ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
151ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note that the function has intimate knowledge of how different
152ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        libc versions add symbols to the executable and thus is probably
153ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        only useable for executables compiled using gcc.
154ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
155ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The file is read and scanned in chunks of chunksize bytes.
156ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
157ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
158ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if hasattr(os.path, 'realpath'):
159ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Python 2.2 introduced os.path.realpath(); it is used
160ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # here to work around problems with Cygwin not being
161ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # able to open symlinks for reading
162ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        executable = os.path.realpath(executable)
163ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    f = open(executable,'rb')
164ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    binary = f.read(chunksize)
165ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    pos = 0
166ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    while 1:
167ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        m = _libc_search.search(binary,pos)
168ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if not m:
169ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            binary = f.read(chunksize)
170ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if not binary:
171ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                break
172ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            pos = 0
173ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            continue
174ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
175ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if libcinit and not lib:
176ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            lib = 'libc'
177ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif glibc:
178ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if lib != 'glibc':
179ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                lib = 'glibc'
180ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                version = glibcversion
181ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif glibcversion > version:
182ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                version = glibcversion
183ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif so:
184ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if lib != 'glibc':
185ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                lib = 'libc'
186ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if soversion and soversion > version:
187ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    version = soversion
188ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if threads and version[-len(threads):] != threads:
189ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    version = version + threads
190ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        pos = m.end()
191ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    f.close()
192ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return lib,version
193ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
194ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _dist_try_harder(distname,version,id):
195ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
196ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Tries some special tricks to get the distribution
197ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        information in case the default method fails.
198ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
199ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Currently supports older SuSE Linux, Caldera OpenLinux and
200ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Slackware Linux distributions.
201ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
202ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
203ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if os.path.exists('/var/adm/inst-log/info'):
204ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # SuSE Linux stores distribution information in that file
205ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        info = open('/var/adm/inst-log/info').readlines()
206ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        distname = 'SuSE'
207ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        for line in info:
208ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            tv = string.split(line)
209ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if len(tv) == 2:
210ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                tag,value = tv
211ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
212ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                continue
213ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if tag == 'MIN_DIST_VERSION':
214ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                version = string.strip(value)
215ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif tag == 'DIST_IDENT':
216ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                values = string.split(value,'-')
217ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                id = values[2]
218ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return distname,version,id
219ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
220ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if os.path.exists('/etc/.installed'):
221ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
222ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        info = open('/etc/.installed').readlines()
223ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        for line in info:
224ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            pkg = string.split(line,'-')
225ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
226ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # XXX does Caldera support non Intel platforms ? If yes,
227ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                #     where can we find the needed id ?
228ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                return 'OpenLinux',pkg[1],id
229ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
230ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if os.path.isdir('/usr/lib/setup'):
231ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Check for slackware verson tag file (thanks to Greg Andruk)
232ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        verfiles = os.listdir('/usr/lib/setup')
233ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        for n in range(len(verfiles)-1, -1, -1):
234ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if verfiles[n][:14] != 'slack-version-':
235ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                del verfiles[n]
236ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if verfiles:
237ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            verfiles.sort()
238ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            distname = 'slackware'
239ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = verfiles[-1][14:]
240ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            return distname,version,id
241ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
242ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return distname,version,id
243ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
244ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_release_filename = re.compile(r'(\w+)[-_](release|version)')
245ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_lsb_release_version = re.compile(r'(.+)'
246ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                   ' release '
247ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                   '([\d.]+)'
248ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                   '[^(]*(?:\((.+)\))?')
249ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_release_version = re.compile(r'([^0-9]+)'
250ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                               '(?: release )?'
251ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                               '([\d.]+)'
252ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                               '[^(]*(?:\((.+)\))?')
253ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
254ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# See also http://www.novell.com/coolsolutions/feature/11251.html
255ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# and http://linuxmafia.com/faq/Admin/release-files.html
256ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# and http://data.linux-ntfs.org/rpm/whichrpm
257ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html
258ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
259ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_supported_dists = (
260ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'SuSE', 'debian', 'fedora', 'redhat', 'centos',
261ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
262ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'UnitedLinux', 'turbolinux')
263ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
264ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _parse_release_file(firstline):
265ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
266ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Default to empty 'version' and 'id' strings.  Both defaults are used
267ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # when 'firstline' is empty.  'id' defaults to empty when an id can not
268ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # be deduced.
269ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    version = ''
270ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    id = ''
271ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
272ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Parse the first line
273ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    m = _lsb_release_version.match(firstline)
274ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if m is not None:
275ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # LSB format: "distro release x.x (codename)"
276ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return tuple(m.groups())
277ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
278ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Pre-LSB format: "distro x.x (codename)"
279ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    m = _release_version.match(firstline)
280ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if m is not None:
281ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return tuple(m.groups())
282ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
283ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Unkown format... take the first two words
284ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    l = string.split(string.strip(firstline))
285ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if l:
286ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version = l[0]
287ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if len(l) > 1:
288ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            id = l[1]
289ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return '', version, id
290ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
291ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef linux_distribution(distname='', version='', id='',
292ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
293ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                       supported_dists=_supported_dists,
294ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                       full_distribution_name=1):
295ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
296ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Tries to determine the name of the Linux OS distribution name.
297ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
298ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The function first looks for a distribution release file in
299ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        /etc and then reverts to _dist_try_harder() in case no
300ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        suitable files are found.
301ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
302ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        supported_dists may be given to define the set of Linux
303ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        distributions to look for. It defaults to a list of currently
304ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        supported Linux distributions identified by their release file
305ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name.
306ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
307ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        If full_distribution_name is true (default), the full
308ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        distribution read from the OS is returned. Otherwise the short
309ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name taken from supported_dists is used.
310ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
311ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Returns a tuple (distname,version,id) which default to the
312ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        args given as parameters.
313ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
314ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
315ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
316ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        etc = os.listdir('/etc')
317ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except os.error:
318ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Probably not a Unix system
319ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return distname,version,id
320ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    etc.sort()
321ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    for file in etc:
322ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        m = _release_filename.match(file)
323ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if m is not None:
324ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            _distname,dummy = m.groups()
325ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if _distname in supported_dists:
326ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                distname = _distname
327ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                break
328ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
329ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return _dist_try_harder(distname,version,id)
330ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
331ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Read the first line
332ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    f = open('/etc/'+file, 'r')
333ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    firstline = f.readline()
334ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    f.close()
335ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    _distname, _version, _id = _parse_release_file(firstline)
336ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
337ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if _distname and full_distribution_name:
338ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        distname = _distname
339ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if _version:
340ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version = _version
341ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if _id:
342ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        id = _id
343ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return distname, version, id
344ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
345ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# To maintain backwards compatibility:
346ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
347ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef dist(distname='',version='',id='',
348ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
349ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh         supported_dists=_supported_dists):
350ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
351ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Tries to determine the name of the Linux OS distribution name.
352ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
353ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The function first looks for a distribution release file in
354ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        /etc and then reverts to _dist_try_harder() in case no
355ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        suitable files are found.
356ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
357ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Returns a tuple (distname,version,id) which default to the
358ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        args given as parameters.
359ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
360ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
361ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return linux_distribution(distname, version, id,
362ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                              supported_dists=supported_dists,
363ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                              full_distribution_name=0)
364ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
365ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass _popen:
366ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
367ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Fairly portable (alternative) popen implementation.
368ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
369ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        This is mostly needed in case os.popen() is not available, or
370ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        doesn't work as advertised, e.g. in Win9X GUI programs like
371ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        PythonWin or IDLE.
372ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
373ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Writing to the pipe is currently not supported.
374ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
375ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
376ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    tmpfile = ''
377ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    pipe = None
378ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    bufsize = None
379ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    mode = 'r'
380ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
381ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    def __init__(self,cmd,mode='r',bufsize=None):
382ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
383ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if mode != 'r':
384ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            raise ValueError,'popen()-emulation only supports read mode'
385ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import tempfile
386ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        self.tmpfile = tmpfile = tempfile.mktemp()
387ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        os.system(cmd + ' > %s' % tmpfile)
388ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        self.pipe = open(tmpfile,'rb')
389ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        self.bufsize = bufsize
390ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        self.mode = mode
391ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
392ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    def read(self):
393ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
394ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return self.pipe.read()
395ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
396ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    def readlines(self):
397ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
398ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if self.bufsize is not None:
399ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            return self.pipe.readlines()
400ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
401ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    def close(self,
402ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
403ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh              remove=os.unlink,error=os.error):
404ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
405ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if self.pipe:
406ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            rc = self.pipe.close()
407ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
408ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            rc = 255
409ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if self.tmpfile:
410ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            try:
411ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                remove(self.tmpfile)
412ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            except error:
413ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                pass
414ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return rc
415ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
416ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Alias
417ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    __del__ = close
418ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
419ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef popen(cmd, mode='r', bufsize=None):
420ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
421ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Portable popen() interface.
422ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
423ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Find a working popen implementation preferring win32pipe.popen
424ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # over os.popen over _popen
425ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    popen = None
426ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if os.environ.get('OS','') == 'Windows_NT':
427ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # On NT win32pipe should work; on Win9x it hangs due to bugs
428ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # in the MS C lib (see MS KnowledgeBase article Q150956)
429ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
430ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            import win32pipe
431ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except ImportError:
432ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            pass
433ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
434ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            popen = win32pipe.popen
435ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if popen is None:
436ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if hasattr(os,'popen'):
437ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            popen = os.popen
438ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # Check whether it works... it doesn't in GUI programs
439ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # on Windows platforms
440ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if sys.platform == 'win32': # XXX Others too ?
441ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                try:
442ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    popen('')
443ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                except os.error:
444ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    popen = _popen
445ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
446ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            popen = _popen
447ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if bufsize is None:
448ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return popen(cmd,mode)
449ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
450ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return popen(cmd,mode,bufsize)
451ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
452ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _norm_version(version, build=''):
453ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
454ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Normalize the version and build strings and return a single
455ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version string using the format major.minor.build (or patchlevel).
456ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
457ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    l = string.split(version,'.')
458ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if build:
459ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        l.append(build)
460ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
461ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        ints = map(int,l)
462ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ValueError:
463ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        strings = l
464ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
465ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        strings = map(str,ints)
466ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    version = string.join(strings[:3],'.')
467ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return version
468ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
469ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
470ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                         '.*'
471ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                         '\[.* ([\d.]+)\])')
472ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
473ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Examples of VER command output:
474ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
475ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#   Windows 2000:  Microsoft Windows 2000 [Version 5.00.2195]
476ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#   Windows XP:    Microsoft Windows XP [Version 5.1.2600]
477ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#   Windows Vista: Microsoft Windows [Version 6.0.6002]
478ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh#
479ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Note that the "Version" string gets localized on different
480ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Windows versions.
481ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
482ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _syscmd_ver(system='', release='', version='',
483ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
484ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh               supported_platforms=('win32','win16','dos','os2')):
485ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
486ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Tries to figure out the OS version used and returns
487ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        a tuple (system,release,version).
488ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
489ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        It uses the "ver" shell command for this which is known
490ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        to exists on Windows, DOS and OS/2. XXX Others too ?
491ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
492ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        In case this fails, the given parameters are used as
493ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        defaults.
494ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
495ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
496ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys.platform not in supported_platforms:
497ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return system,release,version
498ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
499ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Try some common cmd strings
500ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    for cmd in ('ver','command /c ver','cmd /c ver'):
501ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
502ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            pipe = popen(cmd)
503ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            info = pipe.read()
504ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if pipe.close():
505ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                raise os.error,'command failed'
506ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # XXX How can I suppress shell errors from being written
507ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            #     to stderr ?
508ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except os.error,why:
509ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            #print 'Command %s failed: %s' % (cmd,why)
510ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            continue
511ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except IOError,why:
512ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            #print 'Command %s failed: %s' % (cmd,why)
513ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            continue
514ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
515ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            break
516ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
517ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return system,release,version
518ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
519ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Parse the output
520ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    info = string.strip(info)
521ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    m = _ver_output.match(info)
522ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if m is not None:
523ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system,release,version = m.groups()
524ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Strip trailing dots from version and release
525ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if release[-1] == '.':
526ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = release[:-1]
527ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if version[-1] == '.':
528ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = version[:-1]
529ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Normalize the version and build strings (eliminating additional
530ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # zeros)
531ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version = _norm_version(version)
532ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return system,release,version
533ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
534ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _win32_getvalue(key,name,default=''):
535ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
536ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Read a value for name from the registry key.
537ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
538ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        In case this fails, default is returned.
539ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
540ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
541ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
542ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Use win32api if available
543ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        from win32api import RegQueryValueEx
544ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
545ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # On Python 2.0 and later, emulate using _winreg
546ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import _winreg
547ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        RegQueryValueEx = _winreg.QueryValueEx
548ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
549ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return RegQueryValueEx(key,name)
550ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except:
551ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
552ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
553ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef win32_ver(release='',version='',csd='',ptype=''):
554ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
555ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Get additional version information from the Windows Registry
556ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        and return a tuple (version,csd,ptype) referring to version
557ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        number, CSD level (service pack), and OS type (multi/single
558ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor).
559ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
560ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        As a hint: ptype returns 'Uniprocessor Free' on single
561ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor NT machines and 'Multiprocessor Free' on multi
562ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor machines. The 'Free' refers to the OS version being
563ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        free of debugging code. It could also state 'Checked' which
564ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        means the OS version uses debugging code, i.e. code that
565ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        checks arguments, ranges, etc. (Thomas Heller).
566ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
567ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note: this function works best with Mark Hammond's win32
568ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        package installed, but also on Python 2.3 and later. It
569ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        obviously only runs on Win32 compatible platforms.
570ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
571ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
572ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # XXX Is there any way to find out the processor type on WinXX ?
573ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # XXX Is win32 available on Windows CE ?
574ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #
575ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Adapted from code posted by Karl Putland to comp.lang.python.
576ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #
577ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # The mappings between reg. values and release names can be found
578ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp
579ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
580ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Import the needed APIs
581ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
582ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import win32api
583ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        from win32api import RegQueryValueEx, RegOpenKeyEx, \
584ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh             RegCloseKey, GetVersionEx
585ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \
586ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh             VER_PLATFORM_WIN32_WINDOWS, VER_NT_WORKSTATION
587ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
588ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Emulate the win32api module using Python APIs
589ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
590ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            sys.getwindowsversion
591ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except AttributeError:
592ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # No emulation possible, so return the defaults...
593ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            return release,version,csd,ptype
594ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
595ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # Emulation using _winreg (added in Python 2.0) and
596ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # sys.getwindowsversion() (added in Python 2.3)
597ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            import _winreg
598ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            GetVersionEx = sys.getwindowsversion
599ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            RegQueryValueEx = _winreg.QueryValueEx
600ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            RegOpenKeyEx = _winreg.OpenKeyEx
601ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            RegCloseKey = _winreg.CloseKey
602ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            HKEY_LOCAL_MACHINE = _winreg.HKEY_LOCAL_MACHINE
603ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            VER_PLATFORM_WIN32_WINDOWS = 1
604ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            VER_PLATFORM_WIN32_NT = 2
605ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            VER_NT_WORKSTATION = 1
606ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            VER_NT_SERVER = 3
607ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            REG_SZ = 1
608ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
609ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Find out the registry key and some general version infos
610ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    winver = GetVersionEx()
611ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    maj,min,buildno,plat,csd = winver
612ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF)
613ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if hasattr(winver, "service_pack"):
614ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if winver.service_pack != "":
615ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            csd = 'SP%s' % winver.service_pack_major
616ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
617ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if csd[:13] == 'Service Pack ':
618ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            csd = 'SP' + csd[13:]
619ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
620ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if plat == VER_PLATFORM_WIN32_WINDOWS:
621ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
622ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Try to guess the release name
623ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if maj == 4:
624ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if min == 0:
625ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = '95'
626ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 10:
627ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = '98'
628ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 90:
629ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = 'Me'
630ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
631ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = 'postMe'
632ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif maj == 5:
633ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = '2000'
634ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
635ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif plat == VER_PLATFORM_WIN32_NT:
636ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
637ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if maj <= 4:
638ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = 'NT'
639ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif maj == 5:
640ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if min == 0:
641ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = '2000'
642ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 1:
643ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = 'XP'
644ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 2:
645ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = '2003Server'
646ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
647ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = 'post2003'
648ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif maj == 6:
649ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if hasattr(winver, "product_type"):
650ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                product_type = winver.product_type
651ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
652ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                product_type = VER_NT_WORKSTATION
653ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # Without an OSVERSIONINFOEX capable sys.getwindowsversion(),
654ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # or help from the registry, we cannot properly identify
655ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # non-workstation versions.
656ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                try:
657ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
658ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    name, type = RegQueryValueEx(key, "ProductName")
659ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    # Discard any type that isn't REG_SZ
660ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    if type == REG_SZ and name.find("Server") != -1:
661ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                        product_type = VER_NT_SERVER
662ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                except WindowsError:
663ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    # Use default of VER_NT_WORKSTATION
664ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    pass
665ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
666ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if min == 0:
667ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if product_type == VER_NT_WORKSTATION:
668ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = 'Vista'
669ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
670ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = '2008Server'
671ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 1:
672ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if product_type == VER_NT_WORKSTATION:
673ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = '7'
674ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
675ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = '2008ServerR2'
676ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif min == 2:
677ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if product_type == VER_NT_WORKSTATION:
678ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = '8'
679ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
680ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = '2012Server'
681ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
682ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = 'post2012Server'
683ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
684ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
685ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if not release:
686ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # E.g. Win3.1 with win32s
687ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = '%i.%i' % (maj,min)
688ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return release,version,csd,ptype
689ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
690ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Open the registry key
691ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
692ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
693ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Get a value to make sure the key exists...
694ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        RegQueryValueEx(keyCurVer, 'SystemRoot')
695ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except:
696ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return release,version,csd,ptype
697ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
698ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Parse values
699ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #subversion = _win32_getvalue(keyCurVer,
700ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #                            'SubVersionNumber',
701ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #                            ('',1))[0]
702ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #if subversion:
703ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #   release = release + subversion # 95a, 95b, etc.
704ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    build = _win32_getvalue(keyCurVer,
705ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                            'CurrentBuildNumber',
706ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                            ('',1))[0]
707ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    ptype = _win32_getvalue(keyCurVer,
708ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                           'CurrentType',
709ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                           (ptype,1))[0]
710ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
711ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Normalize version
712ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    version = _norm_version(version,build)
713ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
714ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Close key
715ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    RegCloseKey(keyCurVer)
716ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return release,version,csd,ptype
717ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
718ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _mac_ver_lookup(selectors,default=None):
719ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
720ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    from gestalt import gestalt
721ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    import MacOS
722ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    l = []
723ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    append = l.append
724ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    for selector in selectors:
725ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
726ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            append(gestalt(selector))
727ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except (RuntimeError, MacOS.Error):
728ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            append(default)
729ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return l
730ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
731ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _bcd2str(bcd):
732ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
733ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return hex(bcd)[2:]
734ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
735ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _mac_ver_gestalt():
736ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
737ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Thanks to Mark R. Levinson for mailing documentation links and
738ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        code examples for this function. Documentation for the
739ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        gestalt() API is available online at:
740ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
741ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh           http://www.rgaros.nl/gestalt/
742ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
743ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Check whether the version info module is available
744ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
745ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import gestalt
746ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import MacOS
747ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
748ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return None
749ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Get the infos
750ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    sysv,sysa = _mac_ver_lookup(('sysv','sysa'))
751ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Decode the infos
752ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sysv:
753ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        major = (sysv & 0xFF00) >> 8
754ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        minor = (sysv & 0x00F0) >> 4
755ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        patch = (sysv & 0x000F)
756ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
757ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if (major, minor) >= (10, 4):
758ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # the 'sysv' gestald cannot return patchlevels
759ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # higher than 9. Apple introduced 3 new
760ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # gestalt codes in 10.4 to deal with this
761ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # issue (needed because patch levels can
762ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # run higher than 9, such as 10.4.11)
763ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3'))
764ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = '%i.%i.%i' %(major, minor, patch)
765ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
766ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = '%s.%i.%i' % (_bcd2str(major),minor,patch)
767ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
768ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sysa:
769ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        machine = {0x1: '68k',
770ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                   0x2: 'PowerPC',
771ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                   0xa: 'i386'}.get(sysa,'')
772ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
773ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    versioninfo=('', '', '')
774ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return release,versioninfo,machine
775ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
776ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _mac_ver_xml():
777ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    fn = '/System/Library/CoreServices/SystemVersion.plist'
778ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not os.path.exists(fn):
779ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return None
780ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
781ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
782ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import plistlib
783ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
784ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return None
785ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
786ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    pl = plistlib.readPlist(fn)
787ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    release = pl['ProductVersion']
788ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    versioninfo=('', '', '')
789ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    machine = os.uname()[4]
790ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if machine in ('ppc', 'Power Macintosh'):
791ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # for compatibility with the gestalt based code
792ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        machine = 'PowerPC'
793ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
794ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return release,versioninfo,machine
795ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
796ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
797ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef mac_ver(release='',versioninfo=('','',''),machine=''):
798ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
799ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Get MacOS version information and return it as tuple (release,
800ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        versioninfo, machine) with versioninfo being a tuple (version,
801ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        dev_stage, non_release_version).
802ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
803ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Entries which cannot be determined are set to the paramter values
804ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        which default to ''. All tuple entries are strings.
805ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
806ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
807ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # First try reading the information from an XML file which should
808ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # always be present
809ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    info = _mac_ver_xml()
810ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if info is not None:
811ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return info
812ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
813ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # If that doesn't work for some reason fall back to reading the
814ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # information using gestalt calls.
815ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    info = _mac_ver_gestalt()
816ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if info is not None:
817ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return info
818ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
819ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # If that also doesn't work return the default values
820ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return release,versioninfo,machine
821ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
822ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _java_getprop(name,default):
823ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
824ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    from java.lang import System
825ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
826ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        value = System.getProperty(name)
827ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if value is None:
828ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            return default
829ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return value
830ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except AttributeError:
831ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
832ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
833ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')):
834ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
835ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Version interface for Jython.
836ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
837ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
838ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
839ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        tuple (os_name,os_version,os_arch).
840ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
841ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Values which cannot be determined are set to the defaults
842ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        given as parameters (which all default to '').
843ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
844ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
845ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Import the needed APIs
846ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
847ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import java.lang
848ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
849ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return release,vendor,vminfo,osinfo
850ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
851ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vendor = _java_getprop('java.vendor', vendor)
852ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    release = _java_getprop('java.version', release)
853ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vm_name, vm_release, vm_vendor = vminfo
854ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vm_name = _java_getprop('java.vm.name', vm_name)
855ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
856ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vm_release = _java_getprop('java.vm.version', vm_release)
857ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    vminfo = vm_name, vm_release, vm_vendor
858ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    os_name, os_version, os_arch = osinfo
859ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    os_arch = _java_getprop('java.os.arch', os_arch)
860ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    os_name = _java_getprop('java.os.name', os_name)
861ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    os_version = _java_getprop('java.os.version', os_version)
862ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    osinfo = os_name, os_version, os_arch
863ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
864ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return release, vendor, vminfo, osinfo
865ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
866ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### System name aliasing
867ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
868ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef system_alias(system,release,version):
869ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
870ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns (system,release,version) aliased to common
871ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        marketing names used for some systems.
872ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
873ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        It also does some reordering of the information in some cases
874ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        where it would otherwise cause confusion.
875ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
876ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
877ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if system == 'Rhapsody':
878ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Apple's BSD derivative
879ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # XXX How can we determine the marketing release number ?
880ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return 'MacOS X Server',system+release,version
881ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
882ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system == 'SunOS':
883ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Sun's OS
884ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if release < '5':
885ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # These releases use the old name SunOS
886ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            return system,release,version
887ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Modify release (marketing release = SunOS release - 3)
888ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        l = string.split(release,'.')
889ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if l:
890ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            try:
891ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                major = int(l[0])
892ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            except ValueError:
893ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                pass
894ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
895ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                major = major - 3
896ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                l[0] = str(major)
897ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                release = string.join(l,'.')
898ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if release < '6':
899ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system = 'Solaris'
900ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
901ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # XXX Whatever the new SunOS marketing name is...
902ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system = 'Solaris'
903ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
904ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system == 'IRIX64':
905ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
906ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # is really a version and not a different platform, since 32-bit
907ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # apps are also supported..
908ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system = 'IRIX'
909ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if version:
910ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = version + ' (64bit)'
911ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
912ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = '64bit'
913ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
914ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system in ('win32','win16'):
915ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # In case one of the other tricks
916ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system = 'Windows'
917ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
918ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return system,release,version
919ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
920ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Various internal helpers
921ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
922ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _platform(*args):
923ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
924ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Helper to format the platform string in a filename
925ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        compatible format e.g. "system-version-machine".
926ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
927ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Format the platform string
928ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = string.join(
929ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        map(string.strip,
930ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            filter(len, args)),
931ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        '-')
932ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
933ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Cleanup some possible filename obstacles...
934ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    replace = string.replace
935ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,' ','_')
936ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,'/','-')
937ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,'\\','-')
938ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,':','-')
939ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,';','-')
940ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,'"','-')
941ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,'(','-')
942ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,')','-')
943ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
944ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # No need to report 'unknown' information...
945ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    platform = replace(platform,'unknown','')
946ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
947ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Fold '--'s and remove trailing '-'
948ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    while 1:
949ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        cleaned = replace(platform,'--','-')
950ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if cleaned == platform:
951ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            break
952ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        platform = cleaned
953ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    while platform[-1] == '-':
954ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        platform = platform[:-1]
955ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
956ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return platform
957ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
958ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _node(default=''):
959ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
960ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Helper to determine the node name of this machine.
961ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
962ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
963ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import socket
964ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except ImportError:
965ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # No sockets...
966ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
967ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
968ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return socket.gethostname()
969ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except socket.error:
970ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Still not working...
971ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
972ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
973ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# os.path.abspath is new in Python 1.5.2:
974ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehif not hasattr(os.path,'abspath'):
975ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
976ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    def _abspath(path,
977ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
978ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                 isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd,
979ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                 normpath=os.path.normpath):
980ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
981ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if not isabs(path):
982ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            path = join(getcwd(), path)
983ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return normpath(path)
984ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
985ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehelse:
986ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
987ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    _abspath = os.path.abspath
988ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
989ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _follow_symlinks(filepath):
990ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
991ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ In case filepath is a symlink, follow it until a
992ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        real file is reached.
993ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
994ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    filepath = _abspath(filepath)
995ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    while os.path.islink(filepath):
996ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        filepath = os.path.normpath(
997ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            os.path.join(os.path.dirname(filepath),os.readlink(filepath)))
998ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return filepath
999ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1000ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _syscmd_uname(option,default=''):
1001ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1002ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Interface to the system's uname command.
1003ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1004ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
1005ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # XXX Others too ?
1006ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1007ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
1008ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        f = os.popen('uname %s 2> %s' % (option, DEV_NULL))
1009ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except (AttributeError,os.error):
1010ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1011ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    output = string.strip(f.read())
1012ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    rc = f.close()
1013ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not output or rc:
1014ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1015ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1016ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return output
1017ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1018ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _syscmd_file(target,default=''):
1019ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1020ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Interface to the system's file command.
1021ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1022ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The function uses the -b option of the file command to have it
1023ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        ommit the filename in its output and if possible the -L option
1024ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        to have the command follow symlinks. It returns default in
1025ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        case the command should fail.
1026ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1027ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1028ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1029ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # We do the import here to avoid a bootstrap issue.
1030ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # See c73b90b6dadd changeset.
1031ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #
1032ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # [..]
1033ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # ranlib libpython2.7.a
1034ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # gcc   -o python \
1035ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #        Modules/python.o \
1036ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #        libpython2.7.a -lsocket -lnsl -ldl    -lm
1037ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Traceback (most recent call last):
1038ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #  File "./setup.py", line 8, in <module>
1039ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #    from platform import machine as platform_machine
1040ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #  File "[..]/build/Lib/platform.py", line 116, in <module>
1041ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #    import sys,string,os,re,subprocess
1042ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #  File "[..]/build/Lib/subprocess.py", line 429, in <module>
1043ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #    import select
1044ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # ImportError: No module named select
1045ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1046ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    import subprocess
1047ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1048ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
1049ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # XXX Others too ?
1050ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1051ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    target = _follow_symlinks(target)
1052ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
1053ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        proc = subprocess.Popen(['file', target],
1054ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1055ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1056ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except (AttributeError,os.error):
1057ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1058ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    output = proc.communicate()[0]
1059ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    rc = proc.wait()
1060ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not output or rc:
1061ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return default
1062ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1063ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return output
1064ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1065ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Information about the used architecture
1066ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1067ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Default values for architecture; non-empty strings override the
1068ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# defaults given as parameters
1069ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_default_architecture = {
1070ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'win32': ('','WindowsPE'),
1071ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'win16': ('','Windows'),
1072ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    'dos': ('','MSDOS'),
1073ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh}
1074ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1075ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_architecture_split = re.compile(r'[\s,]').split
1076ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1077ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef architecture(executable=sys.executable,bits='',linkage=''):
1078ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1079ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Queries the given executable (defaults to the Python interpreter
1080ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        binary) for various architecture information.
1081ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1082ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Returns a tuple (bits,linkage) which contains information about
1083ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        the bit architecture and the linkage format used for the
1084ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        executable. Both values are returned as strings.
1085ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1086ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Values that cannot be determined are returned as given by the
1087ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        parameter presets. If bits is given as '', the sizeof(pointer)
1088ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        (or sizeof(long) on Python version < 1.5.2) is used as
1089ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        indicator for the supported pointer size.
1090ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1091ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The function relies on the system's "file" command to do the
1092ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        actual work. This is available on most if not all Unix
1093ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        platforms. On some non-Unix platforms where the "file" command
1094ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        does not exist and the executable is set to the Python interpreter
1095ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        binary defaults from _default_architecture are used.
1096ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1097ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1098ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Use the sizeof(pointer) as default number of bits if nothing
1099ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # else is given as default.
1100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not bits:
1101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        import struct
1102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
1103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            size = struct.calcsize('P')
1104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except struct.error:
1105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # Older installations can only query longs
1106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            size = struct.calcsize('l')
1107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        bits = str(size*8) + 'bit'
1108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Get data from the 'file' system command
1110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if executable:
1111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        output = _syscmd_file(executable, '')
1112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        output = ''
1114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1115ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not output and \
1116ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh       executable == sys.executable:
1117ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # "file" command did not return anything; we'll try to provide
1118ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # some sensible defaults then...
1119ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if sys.platform in _default_architecture:
1120ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            b, l = _default_architecture[sys.platform]
1121ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if b:
1122ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                bits = b
1123ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if l:
1124ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                linkage = l
1125ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return bits, linkage
1126ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1127ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Split the output into a list of strings omitting the filename
1128ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    fileout = _architecture_split(output)[1:]
1129ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1130ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if 'executable' not in fileout:
1131ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Format not supported
1132ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return bits,linkage
1133ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1134ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Bits
1135ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if '32-bit' in fileout:
1136ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        bits = '32bit'
1137ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif 'N32' in fileout:
1138ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # On Irix only
1139ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        bits = 'n32bit'
1140ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif '64-bit' in fileout:
1141ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        bits = '64bit'
1142ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1143ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Linkage
1144ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if 'ELF' in fileout:
1145ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        linkage = 'ELF'
1146ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif 'PE' in fileout:
1147ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # E.g. Windows uses this format
1148ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if 'Windows' in fileout:
1149ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            linkage = 'WindowsPE'
1150ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1151ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            linkage = 'PE'
1152ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif 'COFF' in fileout:
1153ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        linkage = 'COFF'
1154ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif 'MS-DOS' in fileout:
1155ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        linkage = 'MSDOS'
1156ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1157ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # XXX the A.OUT format also falls under this class...
1158ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        pass
1159ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1160ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return bits,linkage
1161ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1162ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Portable uname() interface
1163ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1164ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_uname_cache = None
1165ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1166ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef uname():
1167ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1168ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Fairly portable uname interface. Returns a tuple
1169ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        of strings (system,node,release,version,machine,processor)
1170ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        identifying the underlying platform.
1171ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1172ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note that unlike the os.uname function this also returns
1173ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        possible processor information as an additional tuple entry.
1174ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1175ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Entries which cannot be determined are set to ''.
1176ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1177ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1178ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    global _uname_cache
1179ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    no_os_uname = 0
1180ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1181ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if _uname_cache is not None:
1182ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return _uname_cache
1183ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1184ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    processor = ''
1185ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1186ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Get some infos from the builtin os.uname API...
1187ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    try:
1188ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system,node,release,version,machine = os.uname()
1189ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    except AttributeError:
1190ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        no_os_uname = 1
1191ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1192ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if no_os_uname or not filter(None, (system, node, release, version, machine)):
1193ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Hmm, no there is either no uname or uname has returned
1194ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        #'unknowns'... we'll have to poke around the system then.
1195ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if no_os_uname:
1196ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system = sys.platform
1197ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = ''
1198ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = ''
1199ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            node = _node()
1200ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            machine = ''
1201ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1202ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        use_syscmd_ver = 1
1203ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1204ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Try win32_ver() on win32 platforms
1205ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if system == 'win32':
1206ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release,version,csd,ptype = win32_ver()
1207ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if release and version:
1208ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                use_syscmd_ver = 0
1209ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # Try to use the PROCESSOR_* environment variables
1210ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # available on Win XP and later; see
1211ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # http://support.microsoft.com/kb/888731 and
1212ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
1213ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if not machine:
1214ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # WOW64 processes mask the native architecture
1215ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if "PROCESSOR_ARCHITEW6432" in os.environ:
1216ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    machine = os.environ.get("PROCESSOR_ARCHITEW6432", '')
1217ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
1218ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
1219ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if not processor:
1220ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
1221ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1222ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Try the 'ver' system command available on some
1223ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # platforms
1224ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if use_syscmd_ver:
1225ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system,release,version = _syscmd_ver(system)
1226ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # Normalize system to what win32_ver() normally returns
1227ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # (_syscmd_ver() tends to return the vendor name as well)
1228ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if system == 'Microsoft Windows':
1229ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                system = 'Windows'
1230ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            elif system == 'Microsoft' and release == 'Windows':
1231ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # Under Windows Vista and Windows Server 2008,
1232ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # Microsoft changed the output of the ver command. The
1233ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # release is no longer printed.  This causes the
1234ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                # system and release to be misidentified.
1235ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                system = 'Windows'
1236ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if '6.0' == version[:3]:
1237ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = 'Vista'
1238ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
1239ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    release = ''
1240ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1241ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # In case we still don't know anything useful, we'll try to
1242ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # help ourselves
1243ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if system in ('win32','win16'):
1244ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if not version:
1245ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                if system == 'win32':
1246ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    version = '32bit'
1247ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                else:
1248ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                    version = '16bit'
1249ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system = 'Windows'
1250ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1251ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        elif system[:4] == 'java':
1252ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release,vendor,vminfo,osinfo = java_ver()
1253ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            system = 'Java'
1254ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = string.join(vminfo,', ')
1255ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if not version:
1256ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                version = vendor
1257ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1258ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # System specific extensions
1259ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if system == 'OpenVMS':
1260ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # OpenVMS seems to have release and version mixed up
1261ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if not release or release == '0':
1262ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            release = version
1263ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            version = ''
1264ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Get processor information
1265ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        try:
1266ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            import vms_lib
1267ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        except ImportError:
1268ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            pass
1269ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1270ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
1271ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            if (cpu_number >= 128):
1272ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                processor = 'Alpha'
1273ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            else:
1274ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                processor = 'VAX'
1275ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if not processor:
1276ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Get processor information from the uname system command
1277ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor = _syscmd_uname('-p','')
1278ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1279ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #If any unknowns still exist, replace them with ''s, which are more portable
1280ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if system == 'unknown':
1281ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system = ''
1282ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if node == 'unknown':
1283ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        node = ''
1284ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if release == 'unknown':
1285ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        release = ''
1286ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if version == 'unknown':
1287ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version = ''
1288ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if machine == 'unknown':
1289ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        machine = ''
1290ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if processor == 'unknown':
1291ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor = ''
1292ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1293ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    #  normalize name
1294ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if system == 'Microsoft' and release == 'Windows':
1295ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system = 'Windows'
1296ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        release = 'Vista'
1297ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1298ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    _uname_cache = system,node,release,version,machine,processor
1299ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _uname_cache
1300ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1301ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Direct interfaces to some of the uname() return values
1302ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1303ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef system():
1304ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1305ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
1306ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1307ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be determined.
1308ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1309ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1310ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[0]
1311ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1312ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef node():
1313ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1314ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the computer's network name (which may not be fully
1315ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        qualified)
1316ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1317ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be determined.
1318ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1319ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1320ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[1]
1321ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1322ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef release():
1323ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1324ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the system's release, e.g. '2.2.0' or 'NT'
1325ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1326ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be determined.
1327ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1328ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1329ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[2]
1330ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1331ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef version():
1332ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1333ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the system's release version, e.g. '#3 on degas'
1334ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1335ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be determined.
1336ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1337ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1338ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[3]
1339ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1340ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef machine():
1341ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1342ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the machine type, e.g. 'i386'
1343ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1344ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be determined.
1345ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1346ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1347ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[4]
1348ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1349ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef processor():
1350ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1351ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the (true) processor name, e.g. 'amdk6'
1352ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1353ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        An empty string is returned if the value cannot be
1354ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        determined. Note that many platforms do not provide this
1355ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        information or simply return the same value as for machine(),
1356ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        e.g.  NetBSD does this.
1357ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1358ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1359ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return uname()[5]
1360ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1361ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Various APIs for extracting information from sys.version
1362ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1363ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_sys_version_parser = re.compile(
1364ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    r'([\w.+]+)\s*'
1365ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
1366ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '\[([^\]]+)\]?')
1367ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1368ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_ironpython_sys_version_parser = re.compile(
1369ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    r'IronPython\s*'
1370ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '([\d\.]+)'
1371ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '(?: \(([\d\.]+)\))?'
1372ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    ' on (.NET [\d\.]+)')
1373ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1374ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_pypy_sys_version_parser = re.compile(
1375ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    r'([\w.+]+)\s*'
1376ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
1377ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    '\[PyPy [^\]]+\]?')
1378ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1379ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_sys_version_cache = {}
1380ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1381ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _sys_version(sys_version=None):
1382ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1383ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a parsed version of Python's sys.version as tuple
1384ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        (name, version, branch, revision, buildno, builddate, compiler)
1385ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        referring to the Python implementation name, version, branch,
1386ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        revision, build number, build date/time as string and the compiler
1387ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        identification string.
1388ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1389ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note that unlike the Python sys.version, the returned value
1390ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        for the Python version will always include the patchlevel (it
1391ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        defaults to '.0').
1392ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1393ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The function returns empty strings for tuple entries that
1394ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        cannot be determined.
1395ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1396ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        sys_version may be given to parse an alternative version
1397ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        string, e.g. if the version was read from a different Python
1398ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        interpreter.
1399ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1400ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1401ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Get the Python version
1402ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys_version is None:
1403ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        sys_version = sys.version
1404ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1405ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Try the cache first
1406ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    result = _sys_version_cache.get(sys_version, None)
1407ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if result is not None:
1408ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return result
1409ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1410ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Parse it
1411ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if sys_version[:10] == 'IronPython':
1412ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # IronPython
1413ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name = 'IronPython'
1414ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        match = _ironpython_sys_version_parser.match(sys_version)
1415ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if match is None:
1416ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            raise ValueError(
1417ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                'failed to parse IronPython sys.version: %s' %
1418ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                repr(sys_version))
1419ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version, alt_version, compiler = match.groups()
1420ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        buildno = ''
1421ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        builddate = ''
1422ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1423ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif sys.platform[:4] == 'java':
1424ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Jython
1425ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name = 'Jython'
1426ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        match = _sys_version_parser.match(sys_version)
1427ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if match is None:
1428ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            raise ValueError(
1429ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                'failed to parse Jython sys.version: %s' %
1430ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                repr(sys_version))
1431ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version, buildno, builddate, buildtime, _ = match.groups()
1432ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        compiler = sys.platform
1433ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1434ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif "PyPy" in sys_version:
1435ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # PyPy
1436ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name = "PyPy"
1437ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        match = _pypy_sys_version_parser.match(sys_version)
1438ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if match is None:
1439ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            raise ValueError("failed to parse PyPy sys.version: %s" %
1440ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                             repr(sys_version))
1441ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version, buildno, builddate, buildtime = match.groups()
1442ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        compiler = ""
1443ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1444ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1445ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # CPython
1446ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        match = _sys_version_parser.match(sys_version)
1447ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if match is None:
1448ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            raise ValueError(
1449ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                'failed to parse CPython sys.version: %s' %
1450ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                repr(sys_version))
1451ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version, buildno, builddate, buildtime, compiler = \
1452ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh              match.groups()
1453ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        name = 'CPython'
1454ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        builddate = builddate + ' ' + buildtime
1455ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1456ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if hasattr(sys, 'subversion'):
1457ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # sys.subversion was added in Python 2.5
1458ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        _, branch, revision = sys.subversion
1459ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1460ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        branch = ''
1461ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        revision = ''
1462ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1463ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Add the patchlevel version if missing
1464ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    l = string.split(version, '.')
1465ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if len(l) == 2:
1466ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        l.append('0')
1467ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        version = string.join(l, '.')
1468ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1469ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Build and cache the result
1470ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    result = (name, version, branch, revision, buildno, builddate, compiler)
1471ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    _sys_version_cache[sys_version] = result
1472ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return result
1473ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1474ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_implementation():
1475ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1476ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a string identifying the Python implementation.
1477ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1478ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Currently, the following implementations are identified:
1479ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh          'CPython' (C implementation of Python),
1480ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh          'IronPython' (.NET implementation of Python),
1481ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh          'Jython' (Java implementation of Python),
1482ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh          'PyPy' (Python implementation of Python).
1483ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1484ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1485ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[0]
1486ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1487ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_version():
1488ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1489ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the Python version as string 'major.minor.patchlevel'
1490ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1491ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note that unlike the Python sys.version, the returned value
1492ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        will always include the patchlevel (it defaults to 0).
1493ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1494ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1495ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[1]
1496ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1497ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_version_tuple():
1498ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1499ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns the Python version as tuple (major, minor, patchlevel)
1500ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        of strings.
1501ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1502ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Note that unlike the Python sys.version, the returned value
1503ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        will always include the patchlevel (it defaults to 0).
1504ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1505ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1506ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return tuple(string.split(_sys_version()[1], '.'))
1507ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1508ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_branch():
1509ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1510ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a string identifying the Python implementation
1511ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        branch.
1512ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1513ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        For CPython this is the Subversion branch from which the
1514ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Python binary was built.
1515ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1516ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        If not available, an empty string is returned.
1517ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1518ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1519ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1520ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[2]
1521ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1522ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_revision():
1523ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1524ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a string identifying the Python implementation
1525ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        revision.
1526ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1527ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        For CPython this is the Subversion revision from which the
1528ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Python binary was built.
1529ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1530ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        If not available, an empty string is returned.
1531ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1532ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1533ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[3]
1534ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1535ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_build():
1536ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1537ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a tuple (buildno, builddate) stating the Python
1538ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        build number and date as strings.
1539ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1540ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1541ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[4:6]
1542ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1543ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef python_compiler():
1544ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1545ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a string identifying the compiler used for compiling
1546ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Python.
1547ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1548ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1549ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return _sys_version()[6]
1550ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1551ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### The Opus Magnum of platform strings :-)
1552ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1553ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_platform_cache = {}
1554ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1555ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef platform(aliased=0, terse=0):
1556ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1557ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """ Returns a single string identifying the underlying platform
1558ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        with as much useful information as possible (but no more :).
1559ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1560ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        The output is intended to be human readable rather than
1561ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        machine parseable. It may look different on different
1562ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        platforms and this is intended.
1563ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1564ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        If "aliased" is true, the function will use aliases for
1565ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        various platforms that report system names which differ from
1566ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        their common names, e.g. SunOS will be reported as
1567ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Solaris. The system_alias() function is used to implement
1568ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        this.
1569ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1570ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        Setting terse to true causes the function to return only the
1571ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        absolute minimum information needed to identify the platform.
1572ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1573ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    """
1574ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    result = _platform_cache.get((aliased, terse), None)
1575ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if result is not None:
1576ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        return result
1577ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1578ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Get uname information and then apply platform specific cosmetics
1579ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # to it...
1580ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    system,node,release,version,machine,processor = uname()
1581ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if machine == processor:
1582ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        processor = ''
1583ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if aliased:
1584ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        system,release,version = system_alias(system,release,version)
1585ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1586ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    if system == 'Windows':
1587ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # MS platforms
1588ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        rel,vers,csd,ptype = win32_ver(version)
1589ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if terse:
1590ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release)
1591ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1592ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,version,csd)
1593ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1594ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system in ('Linux',):
1595ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Linux based systems
1596ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        distname,distversion,distid = dist('')
1597ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if distname and not terse:
1598ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,machine,processor,
1599ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 'with',
1600ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 distname,distversion,distid)
1601ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1602ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            # If the distribution name is unknown check for libc vs. glibc
1603ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            libcname,libcversion = libc_ver(sys.executable)
1604ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,machine,processor,
1605ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 'with',
1606ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 libcname+libcversion)
1607ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system == 'Java':
1608ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Java platforms
1609ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        r,v,vminfo,(os_name,os_version,os_arch) = java_ver()
1610ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if terse or not os_name:
1611ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,version)
1612ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1613ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,version,
1614ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 'on',
1615ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh                                 os_name,os_version,os_arch)
1616ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1617ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    elif system == 'MacOS':
1618ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # MacOS platforms
1619ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if terse:
1620ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release)
1621ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1622ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,machine)
1623ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1624ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    else:
1625ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        # Generic handler
1626ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        if terse:
1627ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release)
1628ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh        else:
1629ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            bits,linkage = architecture(sys.executable)
1630ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh            platform = _platform(system,release,machine,processor,bits,linkage)
1631ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1632ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    _platform_cache[(aliased, terse)] = platform
1633ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    return platform
1634ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1635ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh### Command line interface
1636ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh
1637ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehif __name__ == '__main__':
1638ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    # Default is to print the aliased verbose platform string
1639ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    terse = ('terse' in sys.argv or '--terse' in sys.argv)
1640ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
1641ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    print platform(aliased,terse)
1642ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh    sys.exit(0)
1643