types.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #
  2. # SPDX-License-Identifier: GPL-2.0-only
  3. #
  4. import errno
  5. import re
  6. import os
  7. class OEList(list):
  8. """OpenEmbedded 'list' type
  9. Acts as an ordinary list, but is constructed from a string value and a
  10. separator (optional), and re-joins itself when converted to a string with
  11. str(). Set the variable type flag to 'list' to use this type, and the
  12. 'separator' flag may be specified (defaulting to whitespace)."""
  13. name = "list"
  14. def __init__(self, value, separator = None):
  15. if value is not None:
  16. list.__init__(self, value.split(separator))
  17. else:
  18. list.__init__(self)
  19. if separator is None:
  20. self.separator = " "
  21. else:
  22. self.separator = separator
  23. def __str__(self):
  24. return self.separator.join(self)
  25. def choice(value, choices):
  26. """OpenEmbedded 'choice' type
  27. Acts as a multiple choice for the user. To use this, set the variable
  28. type flag to 'choice', and set the 'choices' flag to a space separated
  29. list of valid values."""
  30. if not isinstance(value, str):
  31. raise TypeError("choice accepts a string, not '%s'" % type(value))
  32. value = value.lower()
  33. choices = choices.lower()
  34. if value not in choices.split():
  35. raise ValueError("Invalid choice '%s'. Valid choices: %s" %
  36. (value, choices))
  37. return value
  38. class NoMatch(object):
  39. """Stub python regex pattern object which never matches anything"""
  40. def findall(self, string, flags=0):
  41. return None
  42. def finditer(self, string, flags=0):
  43. return None
  44. def match(self, flags=0):
  45. return None
  46. def search(self, string, flags=0):
  47. return None
  48. def split(self, string, maxsplit=0):
  49. return None
  50. def sub(pattern, repl, string, count=0):
  51. return None
  52. def subn(pattern, repl, string, count=0):
  53. return None
  54. NoMatch = NoMatch()
  55. def regex(value, regexflags=None):
  56. """OpenEmbedded 'regex' type
  57. Acts as a regular expression, returning the pre-compiled regular
  58. expression pattern object. To use this type, set the variable type flag
  59. to 'regex', and optionally, set the 'regexflags' type to a space separated
  60. list of the flags to control the regular expression matching (e.g.
  61. FOO[regexflags] += 'ignorecase'). See the python documentation on the
  62. 're' module for a list of valid flags."""
  63. flagval = 0
  64. if regexflags:
  65. for flag in regexflags.split():
  66. flag = flag.upper()
  67. try:
  68. flagval |= getattr(re, flag)
  69. except AttributeError:
  70. raise ValueError("Invalid regex flag '%s'" % flag)
  71. if not value:
  72. # Let's ensure that the default behavior for an undefined or empty
  73. # variable is to match nothing. If the user explicitly wants to match
  74. # anything, they can match '.*' instead.
  75. return NoMatch
  76. try:
  77. return re.compile(value, flagval)
  78. except re.error as exc:
  79. raise ValueError("Invalid regex value '%s': %s" %
  80. (value, exc.args[0]))
  81. def boolean(value):
  82. """OpenEmbedded 'boolean' type
  83. Valid values for true: 'yes', 'y', 'true', 't', '1'
  84. Valid values for false: 'no', 'n', 'false', 'f', '0', None
  85. """
  86. if value is None:
  87. return False
  88. if isinstance(value, bool):
  89. return value
  90. if not isinstance(value, str):
  91. raise TypeError("boolean accepts a string, not '%s'" % type(value))
  92. value = value.lower()
  93. if value in ('yes', 'y', 'true', 't', '1'):
  94. return True
  95. elif value in ('no', 'n', 'false', 'f', '0'):
  96. return False
  97. raise ValueError("Invalid boolean value '%s'" % value)
  98. def integer(value, numberbase=10):
  99. """OpenEmbedded 'integer' type
  100. Defaults to base 10, but this can be specified using the optional
  101. 'numberbase' flag."""
  102. return int(value, int(numberbase))
  103. _float = float
  104. def float(value, fromhex='false'):
  105. """OpenEmbedded floating point type
  106. To use this type, set the type flag to 'float', and optionally set the
  107. 'fromhex' flag to a true value (obeying the same rules as for the
  108. 'boolean' type) if the value is in base 16 rather than base 10."""
  109. if boolean(fromhex):
  110. return _float.fromhex(value)
  111. else:
  112. return _float(value)
  113. def path(value, relativeto='', normalize='true', mustexist='false'):
  114. value = os.path.join(relativeto, value)
  115. if boolean(normalize):
  116. value = os.path.normpath(value)
  117. if boolean(mustexist):
  118. try:
  119. open(value, 'r')
  120. except IOError as exc:
  121. if exc.errno == errno.ENOENT:
  122. raise ValueError("{0}: {1}".format(value, os.strerror(errno.ENOENT)))
  123. return value
  124. def is_x86(arch):
  125. """
  126. Check whether arch is x86 or x86_64
  127. """
  128. if arch.startswith('x86_') or re.match('i.*86', arch):
  129. return True
  130. else:
  131. return False
  132. def qemu_use_kvm(kvm, target_arch):
  133. """
  134. Enable kvm if target_arch == build_arch or both of them are x86 archs.
  135. """
  136. use_kvm = False
  137. if kvm and boolean(kvm):
  138. build_arch = os.uname()[4]
  139. if is_x86(build_arch) and is_x86(target_arch):
  140. use_kvm = True
  141. elif build_arch == target_arch:
  142. use_kvm = True
  143. return use_kvm