1"""architecture matching 

2 

3@copyright: 2014, Ansgar Burchardt <ansgar@debian.org> 

4@license: GPL-2+ 

5""" 

6 

7# This program is free software; you can redistribute it and/or modify 

8# it under the terms of the GNU General Public License as published by 

9# the Free Software Foundation; either version 2 of the License, or 

10# (at your option) any later version. 

11# 

12# This program is distributed in the hope that it will be useful, 

13# but WITHOUT ANY WARRANTY; without even the implied warranty of 

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

15# GNU General Public License for more details. 

16# 

17# You should have received a copy of the GNU General Public License 

18# along with this program; if not, write to the Free Software 

19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

20 

21import errno 

22 

23 

24def _load_table(path): 

25 table = [] 

26 with open(path, 'r') as fh: 

27 for line in fh: 

28 if not line or line.startswith('#'): 

29 continue 

30 table.append(line.split()) 

31 return table 

32 

33 

34_cached_cputable = None 

35 

36 

37def _cputable(): 

38 global _cached_cputable 

39 if _cached_cputable is None: 

40 _cached_cputable = _load_table('/usr/share/dpkg/cputable') 

41 return _cached_cputable 

42 

43 

44_cached_arch2tuple = None 

45_cached_tuple2arch = None 

46 

47 

48def _tupletable(): 

49 global _cached_arch2tuple, _cached_tuple2arch 

50 if _cached_arch2tuple is None or _cached_tuple2arch is None: 

51 try: 

52 tripletable = False 

53 table = _load_table('/usr/share/dpkg/tupletable') 

54 except OSError as e: 

55 if e.errno != errno.ENOENT: 

56 raise 

57 tripletable = True 

58 table = _load_table('/usr/share/dpkg/triplettable') 

59 

60 arch2tuple = {} 

61 tuple2arch = {} 

62 

63 def add_tuple(tuple, arch): 

64 if tripletable: 64 ↛ 65line 64 didn't jump to line 65, because the condition on line 64 was never true

65 tuple = "base-{}".format(tuple) 

66 arch2tuple[arch] = tuple 

67 tuple2arch[tuple] = arch 

68 

69 for row in table: 

70 if '<cpu>' in row[0] or '<cpu>' in row[1]: 

71 for cpu in _cputable(): 

72 replaced_row = [column.replace('<cpu>', cpu[0]) for column in row] 

73 add_tuple(replaced_row[0], replaced_row[1]) 

74 else: 

75 add_tuple(row[0], row[1]) 

76 

77 _cached_arch2tuple = arch2tuple 

78 _cached_tuple2arch = tuple2arch 

79 return _cached_tuple2arch, _cached_arch2tuple 

80 

81 

82class InvalidArchitecture(Exception): 

83 pass 

84 

85 

86def Debian_arch_to_Debian_tuple(arch: str): 

87 parts = arch.split('-') 

88 

89 # Handle architecture wildcards 

90 if 'any' in parts: 

91 if len(parts) == 4: 91 ↛ 92line 91 didn't jump to line 92, because the condition on line 91 was never true

92 return parts 

93 elif len(parts) == 3: 93 ↛ 94line 93 didn't jump to line 94, because the condition on line 93 was never true

94 return 'any', parts[0], parts[1], parts[2] 

95 elif len(parts) == 2: 95 ↛ 98line 95 didn't jump to line 98, because the condition on line 95 was never false

96 return 'any', 'any', parts[0], parts[1] 

97 else: 

98 return 'any', 'any', 'any', 'any' 

99 

100 if len(parts) == 2 and parts[0] == 'linux': 

101 arch = parts[1] 

102 

103 tuple = _tupletable()[1].get(arch, None) 

104 if tuple is None: 104 ↛ 105line 104 didn't jump to line 105, because the condition on line 104 was never true

105 return None 

106 return tuple.split('-', 3) 

107 

108 

109def match_architecture(arch: str, wildcard: str) -> bool: 

110 # 'all' has no valid tuple 

111 if arch == 'all' or wildcard == 'all': 

112 return arch == wildcard 

113 if wildcard == 'any' or arch == wildcard: 

114 return True 

115 

116 tuple_arch = Debian_arch_to_Debian_tuple(arch) 

117 tuple_wildcard = Debian_arch_to_Debian_tuple(wildcard) 

118 

119 if tuple_arch is None or len(tuple_arch) != 4: 119 ↛ 120line 119 didn't jump to line 120, because the condition on line 119 was never true

120 raise InvalidArchitecture('{0} is not a valid architecture name'.format(arch)) 

121 if tuple_wildcard is None or len(tuple_wildcard) != 4: 121 ↛ 122line 121 didn't jump to line 122, because the condition on line 121 was never true

122 raise InvalidArchitecture('{0} is not a valid architecture name or wildcard'.format(wildcard)) 

123 

124 for i in range(0, 4): 

125 if tuple_arch[i] != tuple_wildcard[i] and tuple_wildcard[i] != 'any': 

126 return False 

127 return True