| """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 () |