mirror of https://github.com/python/cpython
172 lines
6.0 KiB
Python
172 lines
6.0 KiB
Python
"""distutils.util
|
|
|
|
Miscellaneous utility functions -- anything that doesn't fit into
|
|
one of the other *util.py modules.
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import string
|
|
import sys
|
|
from distutils.errors import DistutilsPlatformError
|
|
|
|
def get_host_platform():
|
|
"""Return a string that identifies the current platform. This is used mainly to
|
|
distinguish platform-specific build directories and platform-specific built
|
|
distributions. Typically includes the OS name and version and the
|
|
architecture (as supplied by 'os.uname()'), although the exact information
|
|
included depends on the OS; eg. on Linux, the kernel version isn't
|
|
particularly important.
|
|
|
|
Examples of returned values:
|
|
linux-i586
|
|
linux-alpha (?)
|
|
solaris-2.6-sun4u
|
|
|
|
Windows will return one of:
|
|
win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
|
|
win32 (all others - specifically, sys.platform is returned)
|
|
|
|
For other non-POSIX platforms, currently just returns 'sys.platform'.
|
|
|
|
"""
|
|
if os.name == 'nt':
|
|
if 'amd64' in sys.version.lower():
|
|
return 'win-amd64'
|
|
if '(arm)' in sys.version.lower():
|
|
return 'win-arm32'
|
|
if '(arm64)' in sys.version.lower():
|
|
return 'win-arm64'
|
|
return sys.platform
|
|
|
|
# Set for cross builds explicitly
|
|
if "_PYTHON_HOST_PLATFORM" in os.environ:
|
|
return os.environ["_PYTHON_HOST_PLATFORM"]
|
|
|
|
if os.name != "posix" or not hasattr(os, 'uname'):
|
|
# XXX what about the architecture? NT is Intel or Alpha,
|
|
# Mac OS is M68k or PPC, etc.
|
|
return sys.platform
|
|
|
|
# Try to distinguish various flavours of Unix
|
|
|
|
(osname, host, release, version, machine) = os.uname()
|
|
|
|
# Convert the OS name to lowercase, remove '/' characters, and translate
|
|
# spaces (for "Power Macintosh")
|
|
osname = osname.lower().replace('/', '')
|
|
machine = machine.replace(' ', '_')
|
|
machine = machine.replace('/', '-')
|
|
|
|
if osname[:5] == "linux":
|
|
# At least on Linux/Intel, 'machine' is the processor --
|
|
# i386, etc.
|
|
# XXX what about Alpha, SPARC, etc?
|
|
return "%s-%s" % (osname, machine)
|
|
elif osname[:5] == "sunos":
|
|
if release[0] >= "5": # SunOS 5 == Solaris 2
|
|
osname = "solaris"
|
|
release = "%d.%s" % (int(release[0]) - 3, release[2:])
|
|
# We can't use "platform.architecture()[0]" because a
|
|
# bootstrap problem. We use a dict to get an error
|
|
# if some suspicious happens.
|
|
bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
|
|
machine += ".%s" % bitness[sys.maxsize]
|
|
# fall through to standard osname-release-machine representation
|
|
elif osname[:3] == "aix":
|
|
from _aix_support import aix_platform
|
|
return aix_platform()
|
|
elif osname[:6] == "cygwin":
|
|
osname = "cygwin"
|
|
rel_re = re.compile (r'[\d.]+', re.ASCII)
|
|
m = rel_re.match(release)
|
|
if m:
|
|
release = m.group()
|
|
elif osname[:6] == "darwin":
|
|
import _osx_support, sysconfig
|
|
osname, release, machine = _osx_support.get_platform_osx(
|
|
sysconfig.get_config_vars(),
|
|
osname, release, machine)
|
|
|
|
return "%s-%s-%s" % (osname, release, machine)
|
|
|
|
def get_platform():
|
|
if os.name == 'nt':
|
|
TARGET_TO_PLAT = {
|
|
'x86' : 'win32',
|
|
'x64' : 'win-amd64',
|
|
'arm' : 'win-arm32',
|
|
}
|
|
return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform()
|
|
else:
|
|
return get_host_platform()
|
|
|
|
|
|
# Needed by 'split_quoted()'
|
|
_wordchars_re = _squote_re = _dquote_re = None
|
|
def _init_regex():
|
|
global _wordchars_re, _squote_re, _dquote_re
|
|
_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
|
|
_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
|
|
_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
|
|
|
|
def split_quoted (s):
|
|
"""Split a string up according to Unix shell-like rules for quotes and
|
|
backslashes. In short: words are delimited by spaces, as long as those
|
|
spaces are not escaped by a backslash, or inside a quoted string.
|
|
Single and double quotes are equivalent, and the quote characters can
|
|
be backslash-escaped. The backslash is stripped from any two-character
|
|
escape sequence, leaving only the escaped character. The quote
|
|
characters are stripped from any quoted string. Returns a list of
|
|
words.
|
|
"""
|
|
|
|
# This is a nice algorithm for splitting up a single string, since it
|
|
# doesn't require character-by-character examination. It was a little
|
|
# bit of a brain-bender to get it working right, though...
|
|
if _wordchars_re is None: _init_regex()
|
|
|
|
s = s.strip()
|
|
words = []
|
|
pos = 0
|
|
|
|
while s:
|
|
m = _wordchars_re.match(s, pos)
|
|
end = m.end()
|
|
if end == len(s):
|
|
words.append(s[:end])
|
|
break
|
|
|
|
if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
|
|
words.append(s[:end]) # we definitely have a word delimiter
|
|
s = s[end:].lstrip()
|
|
pos = 0
|
|
|
|
elif s[end] == '\\': # preserve whatever is being escaped;
|
|
# will become part of the current word
|
|
s = s[:end] + s[end+1:]
|
|
pos = end+1
|
|
|
|
else:
|
|
if s[end] == "'": # slurp singly-quoted string
|
|
m = _squote_re.match(s, end)
|
|
elif s[end] == '"': # slurp doubly-quoted string
|
|
m = _dquote_re.match(s, end)
|
|
else:
|
|
raise RuntimeError("this can't happen (bad char '%c')" % s[end])
|
|
|
|
if m is None:
|
|
raise ValueError("bad string (mismatched %s quotes?)" % s[end])
|
|
|
|
(beg, end) = m.span()
|
|
s = s[:beg] + s[beg+1:end-1] + s[end:]
|
|
pos = m.end() - 2
|
|
|
|
if pos >= len(s):
|
|
words.append(s)
|
|
break
|
|
|
|
return words
|
|
|
|
# split_quoted ()
|