Coverage for daklib/architecture.py: 82%
71 statements
« prev ^ index » next coverage.py v7.6.0, created at 2026-03-14 12:19 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2026-03-14 12:19 +0000
1"""architecture matching
3@copyright: 2014, Ansgar Burchardt <ansgar@debian.org>
4@license: GPL-2+
5"""
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
21import errno
22from collections.abc import Sequence
23from functools import cache
26def _load_table(path: str) -> list[list[str]]:
27 table = []
28 with open(path, "r") as fh:
29 for line in fh:
30 if not line or line.startswith("#"):
31 continue
32 table.append(line.split())
33 return table
36@cache
37def _cputable():
38 return _load_table("/usr/share/dpkg/cputable")
41@cache
42def _tupletable() -> tuple[dict[str, str], dict[str, str]]:
43 try:
44 tripletable = False
45 table = _load_table("/usr/share/dpkg/tupletable")
46 except OSError as e:
47 if e.errno != errno.ENOENT:
48 raise
49 tripletable = True
50 table = _load_table("/usr/share/dpkg/triplettable")
52 arch2tuple: dict[str, str] = {}
53 tuple2arch: dict[str, str] = {}
55 def add_tuple(tuple, arch):
56 if tripletable: 56 ↛ 57line 56 didn't jump to line 57 because the condition on line 56 was never true
57 tuple = "base-{}".format(tuple)
58 arch2tuple[arch] = tuple
59 tuple2arch[tuple] = arch
61 for row in table:
62 if "<cpu>" in row[0] or "<cpu>" in row[1]:
63 for cpu in _cputable():
64 replaced_row = [column.replace("<cpu>", cpu[0]) for column in row]
65 add_tuple(replaced_row[0], replaced_row[1])
66 else:
67 add_tuple(row[0], row[1])
69 return tuple2arch, arch2tuple
72class InvalidArchitecture(Exception):
73 pass
76def Debian_arch_to_Debian_tuple(arch: str) -> Sequence[str] | None:
77 parts = arch.split("-")
79 # Handle architecture wildcards
80 if "any" in parts:
81 if len(parts) == 4: 81 ↛ 82line 81 didn't jump to line 82 because the condition on line 81 was never true
82 return parts
83 elif len(parts) == 3: 83 ↛ 84line 83 didn't jump to line 84 because the condition on line 83 was never true
84 return "any", parts[0], parts[1], parts[2]
85 elif len(parts) == 2: 85 ↛ 88line 85 didn't jump to line 88 because the condition on line 85 was always true
86 return "any", "any", parts[0], parts[1]
87 else:
88 return "any", "any", "any", "any"
90 if len(parts) == 2 and parts[0] == "linux":
91 arch = parts[1]
93 tuple = _tupletable()[1].get(arch, None)
94 if tuple is None: 94 ↛ 95line 94 didn't jump to line 95 because the condition on line 94 was never true
95 return None
96 return tuple.split("-", 3)
99def match_architecture(arch: str, wildcard: str) -> bool:
100 # 'all' has no valid tuple
101 if arch == "all" or wildcard == "all":
102 return arch == wildcard
103 if wildcard == "any" or arch == wildcard:
104 return True
106 tuple_arch = Debian_arch_to_Debian_tuple(arch)
107 tuple_wildcard = Debian_arch_to_Debian_tuple(wildcard)
109 if tuple_arch is None or len(tuple_arch) != 4: 109 ↛ 110line 109 didn't jump to line 110 because the condition on line 109 was never true
110 raise InvalidArchitecture("{0} is not a valid architecture name".format(arch))
111 if tuple_wildcard is None or len(tuple_wildcard) != 4: 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true
112 raise InvalidArchitecture(
113 "{0} is not a valid architecture name or wildcard".format(wildcard)
114 )
116 for i in range(0, 4):
117 if tuple_arch[i] != tuple_wildcard[i] and tuple_wildcard[i] != "any":
118 return False
119 return True