mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	 ca066bdbed
			
		
	
	
		ca066bdbed
		
			
		
	
	
	
	
		
			
			distutils was removed in November. However, the c-analyzer relies on it. To solve that here, we vendor the parts the tool needs so it can be run against 3.12+. (Also see gh-92584.) Note that we may end up removing this code later in favor of a solution in common with the peg_generator tool (which also relies on distutils). At the least, the copy here makes sure the c-analyzer tool works on 3.12+ in the meantime.
		
			
				
	
	
		
			171 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
	
		
			6 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 ()
 |