architecture.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """architecture matching
  2. @copyright: 2014, Ansgar Burchardt <ansgar@debian.org>
  3. @license: GPL-2+
  4. """
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. def _load_table(path):
  19. table = []
  20. with open(path, 'r') as fh:
  21. for line in fh:
  22. if not line or line.startswith('#'):
  23. continue
  24. table.append(line.split())
  25. return table
  26. _cached_cputable = None
  27. def _cputable():
  28. global _cached_cputable
  29. if _cached_cputable is None:
  30. _cached_cputable = _load_table('/usr/share/dpkg/cputable')
  31. return _cached_cputable
  32. _cached_arch2triplet = None
  33. _cached_triplet2arch = None
  34. def _triplettable():
  35. global _cached_arch2triplet, _cached_triplet2arch
  36. if _cached_arch2triplet is None or _cached_triplet2arch is None:
  37. table = _load_table('/usr/share/dpkg/triplettable')
  38. arch2triplet = {}
  39. triplet2arch = {}
  40. for row in table:
  41. if '<cpu>' in row[0] or '<cpu>' in row[1]:
  42. for cpu in _cputable():
  43. replaced_row = [ column.replace('<cpu>', cpu[0]) for column in row ]
  44. arch2triplet[replaced_row[1]] = replaced_row[0]
  45. triplet2arch[replaced_row[0]] = replaced_row[1]
  46. else:
  47. arch2triplet[row[1]] = row[0]
  48. triplet2arch[row[0]] = row[1]
  49. _cached_arch2triplet = arch2triplet
  50. _cached_triplet2arch = triplet2arch
  51. return _cached_triplet2arch, _cached_arch2triplet
  52. class InvalidArchitecture(Exception):
  53. pass
  54. def Debian_arch_to_Debian_triplet(arch):
  55. parts = arch.split('-')
  56. # Handle architecture wildcards
  57. if 'any' in parts:
  58. if len(parts) == 3:
  59. return parts
  60. elif len(parts) == 2:
  61. return 'any', parts[0], parts[1]
  62. else:
  63. return 'any', 'any', 'any'
  64. if len(parts) == 2 and parts[0] == 'linux':
  65. arch = parts[1]
  66. triplet = _triplettable()[1].get(arch, None)
  67. if triplet is None:
  68. return None
  69. return triplet.split('-', 2)
  70. def match_architecture(arch, wildcard):
  71. # 'all' has no valid triplet
  72. if arch == 'all' or wildcard == 'all':
  73. return arch == wildcard
  74. if wildcard is 'any' or arch == wildcard:
  75. return True
  76. triplet_arch = Debian_arch_to_Debian_triplet(arch)
  77. triplet_wildcard = Debian_arch_to_Debian_triplet(wildcard)
  78. if triplet_arch is None or len(triplet_arch) != 3:
  79. raise InvalidArchitecture('{0} is not a valid architecture name'.format(arch))
  80. if triplet_wildcard is None or len(triplet_wildcard) != 3:
  81. raise InvalidArchitecture('{0} is not a valid architecture name or wildcard'.format(wildcard))
  82. for i in range(0,3):
  83. if triplet_arch[i] != triplet_wildcard[i] and triplet_wildcard[i] != 'any':
  84. return False
  85. return True