(root)/
Python-3.12.0/
Tools/
c-analyzer/
distutils/
util.py
       1  """distutils.util
       2  
       3  Miscellaneous utility functions -- anything that doesn't fit into
       4  one of the other *util.py modules.
       5  """
       6  
       7  import os
       8  import re
       9  import string
      10  import sys
      11  from distutils.errors import DistutilsPlatformError
      12  
      13  def get_host_platform():
      14      """Return a string that identifies the current platform.  This is used mainly to
      15      distinguish platform-specific build directories and platform-specific built
      16      distributions.  Typically includes the OS name and version and the
      17      architecture (as supplied by 'os.uname()'), although the exact information
      18      included depends on the OS; eg. on Linux, the kernel version isn't
      19      particularly important.
      20  
      21      Examples of returned values:
      22         linux-i586
      23         linux-alpha (?)
      24         solaris-2.6-sun4u
      25  
      26      Windows will return one of:
      27         win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
      28         win32 (all others - specifically, sys.platform is returned)
      29  
      30      For other non-POSIX platforms, currently just returns 'sys.platform'.
      31  
      32      """
      33      if os.name == 'nt':
      34          if 'amd64' in sys.version.lower():
      35              return 'win-amd64'
      36          if '(arm)' in sys.version.lower():
      37              return 'win-arm32'
      38          if '(arm64)' in sys.version.lower():
      39              return 'win-arm64'
      40          return sys.platform
      41  
      42      # Set for cross builds explicitly
      43      if "_PYTHON_HOST_PLATFORM" in os.environ:
      44          return os.environ["_PYTHON_HOST_PLATFORM"]
      45  
      46      if os.name != "posix" or not hasattr(os, 'uname'):
      47          # XXX what about the architecture? NT is Intel or Alpha,
      48          # Mac OS is M68k or PPC, etc.
      49          return sys.platform
      50  
      51      # Try to distinguish various flavours of Unix
      52  
      53      (osname, host, release, version, machine) = os.uname()
      54  
      55      # Convert the OS name to lowercase, remove '/' characters, and translate
      56      # spaces (for "Power Macintosh")
      57      osname = osname.lower().replace('/', '')
      58      machine = machine.replace(' ', '_')
      59      machine = machine.replace('/', '-')
      60  
      61      if osname[:5] == "linux":
      62          # At least on Linux/Intel, 'machine' is the processor --
      63          # i386, etc.
      64          # XXX what about Alpha, SPARC, etc?
      65          return  "%s-%s" % (osname, machine)
      66      elif osname[:5] == "sunos":
      67          if release[0] >= "5":           # SunOS 5 == Solaris 2
      68              osname = "solaris"
      69              release = "%d.%s" % (int(release[0]) - 3, release[2:])
      70              # We can't use "platform.architecture()[0]" because a
      71              # bootstrap problem. We use a dict to get an error
      72              # if some suspicious happens.
      73              bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
      74              machine += ".%s" % bitness[sys.maxsize]
      75          # fall through to standard osname-release-machine representation
      76      elif osname[:3] == "aix":
      77          from _aix_support import aix_platform
      78          return aix_platform()
      79      elif osname[:6] == "cygwin":
      80          osname = "cygwin"
      81          rel_re = re.compile (r'[\d.]+', re.ASCII)
      82          m = rel_re.match(release)
      83          if m:
      84              release = m.group()
      85      elif osname[:6] == "darwin":
      86          import _osx_support, sysconfig
      87          osname, release, machine = _osx_support.get_platform_osx(
      88                                          sysconfig.get_config_vars(),
      89                                          osname, release, machine)
      90  
      91      return "%s-%s-%s" % (osname, release, machine)
      92  
      93  def get_platform():
      94      if os.name == 'nt':
      95          TARGET_TO_PLAT = {
      96              'x86' : 'win32',
      97              'x64' : 'win-amd64',
      98              'arm' : 'win-arm32',
      99          }
     100          return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform()
     101      else:
     102          return get_host_platform()
     103  
     104  
     105  # Needed by 'split_quoted()'
     106  _wordchars_re = _squote_re = _dquote_re = None
     107  def _init_regex():
     108      global _wordchars_re, _squote_re, _dquote_re
     109      _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
     110      _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
     111      _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
     112  
     113  def split_quoted (s):
     114      """Split a string up according to Unix shell-like rules for quotes and
     115      backslashes.  In short: words are delimited by spaces, as long as those
     116      spaces are not escaped by a backslash, or inside a quoted string.
     117      Single and double quotes are equivalent, and the quote characters can
     118      be backslash-escaped.  The backslash is stripped from any two-character
     119      escape sequence, leaving only the escaped character.  The quote
     120      characters are stripped from any quoted string.  Returns a list of
     121      words.
     122      """
     123  
     124      # This is a nice algorithm for splitting up a single string, since it
     125      # doesn't require character-by-character examination.  It was a little
     126      # bit of a brain-bender to get it working right, though...
     127      if _wordchars_re is None: _init_regex()
     128  
     129      s = s.strip()
     130      words = []
     131      pos = 0
     132  
     133      while s:
     134          m = _wordchars_re.match(s, pos)
     135          end = m.end()
     136          if end == len(s):
     137              words.append(s[:end])
     138              break
     139  
     140          if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
     141              words.append(s[:end])       # we definitely have a word delimiter
     142              s = s[end:].lstrip()
     143              pos = 0
     144  
     145          elif s[end] == '\\':            # preserve whatever is being escaped;
     146                                          # will become part of the current word
     147              s = s[:end] + s[end+1:]
     148              pos = end+1
     149  
     150          else:
     151              if s[end] == "'":           # slurp singly-quoted string
     152                  m = _squote_re.match(s, end)
     153              elif s[end] == '"':         # slurp doubly-quoted string
     154                  m = _dquote_re.match(s, end)
     155              else:
     156                  raise RuntimeError("this can't happen (bad char '%c')" % s[end])
     157  
     158              if m is None:
     159                  raise ValueError("bad string (mismatched %s quotes?)" % s[end])
     160  
     161              (beg, end) = m.span()
     162              s = s[:beg] + s[beg+1:end-1] + s[end:]
     163              pos = m.end() - 2
     164  
     165          if pos >= len(s):
     166              words.append(s)
     167              break
     168  
     169      return words
     170  
     171  # split_quoted ()