diff --git a/daklib_arch.py b/daklib_arch.py index 8354de0..99644d8 100644 --- a/daklib_arch.py +++ b/daklib_arch.py @@ -18,6 +18,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import errno + def _load_table(path): table = [] with open(path, 'r') as fh: @@ -34,66 +36,82 @@ def _cputable(): _cached_cputable = _load_table('/usr/share/dpkg/cputable') return _cached_cputable -_cached_arch2triplet = None -_cached_triplet2arch = None -def _triplettable(): - global _cached_arch2triplet, _cached_triplet2arch - if _cached_arch2triplet is None or _cached_triplet2arch is None: - table = _load_table('/usr/share/dpkg/triplettable') - arch2triplet = {} - triplet2arch = {} +_cached_arch2tuple = None +_cached_tuple2arch = None +def _tupletable(): + global _cached_arch2tuple, _cached_tuple2arch + if _cached_arch2tuple is None or _cached_tuple2arch is None: + try: + tripletable = False + table = _load_table('/usr/share/dpkg/tupletable') + except IOError as e: + if e.errno != errno.ENOENT: + raise + tripletable = True + table = _load_table('/usr/share/dpkg/triplettable') + + arch2tuple = {} + tuple2arch = {} + + def add_tuple(tuple, arch): + if tripletable: + tuple = "base-{}".format(tuple) + arch2tuple[arch] = tuple + tuple2arch[tuple] = arch + for row in table: if '' in row[0] or '' in row[1]: for cpu in _cputable(): replaced_row = [ column.replace('', cpu[0]) for column in row ] - arch2triplet[replaced_row[1]] = replaced_row[0] - triplet2arch[replaced_row[0]] = replaced_row[1] + add_tuple(replaced_row[0], replaced_row[1]) else: - arch2triplet[row[1]] = row[0] - triplet2arch[row[0]] = row[1] - _cached_arch2triplet = arch2triplet - _cached_triplet2arch = triplet2arch - return _cached_triplet2arch, _cached_arch2triplet + add_tuple(row[0], row[1]) + + _cached_arch2tuple = arch2tuple + _cached_tuple2arch = tuple2arch + return _cached_tuple2arch, _cached_arch2tuple class InvalidArchitecture(Exception): pass -def Debian_arch_to_Debian_triplet(arch): +def Debian_arch_to_Debian_tuple(arch): parts = arch.split('-') # Handle architecture wildcards if 'any' in parts: - if len(parts) == 3: + if len(parts) == 4: return parts + elif len(parts) == 3: + return 'any', parts[0], parts[1], parts[2] elif len(parts) == 2: - return 'any', parts[0], parts[1] + return 'any', 'any', parts[0], parts[1] else: - return 'any', 'any', 'any' + return 'any', 'any', 'any', 'any' if len(parts) == 2 and parts[0] == 'linux': arch = parts[1] - triplet = _triplettable()[1].get(arch, None) - if triplet is None: + tuple = _tupletable()[1].get(arch, None) + if tuple is None: return None - return triplet.split('-', 2) + return tuple.split('-', 3) def match_architecture(arch, wildcard): - # 'all' has no valid triplet + # 'all' has no valid tuple if arch == 'all' or wildcard == 'all': return arch == wildcard if wildcard is 'any' or arch == wildcard: return True - triplet_arch = Debian_arch_to_Debian_triplet(arch) - triplet_wildcard = Debian_arch_to_Debian_triplet(wildcard) + tuple_arch = Debian_arch_to_Debian_tuple(arch) + tuple_wildcard = Debian_arch_to_Debian_tuple(wildcard) - if triplet_arch is None or len(triplet_arch) != 3: + if tuple_arch is None or len(tuple_arch) != 4: raise InvalidArchitecture('{0} is not a valid architecture name'.format(arch)) - if triplet_wildcard is None or len(triplet_wildcard) != 3: + if tuple_wildcard is None or len(tuple_wildcard) != 4: raise InvalidArchitecture('{0} is not a valid architecture name or wildcard'.format(wildcard)) - for i in range(0,3): - if triplet_arch[i] != triplet_wildcard[i] and triplet_wildcard[i] != 'any': + for i in range(0,4): + if tuple_arch[i] != tuple_wildcard[i] and tuple_wildcard[i] != 'any': return False return True diff --git a/debarch.py b/debarch.py index eafca2d..68744ff 100644 --- a/debarch.py +++ b/debarch.py @@ -19,8 +19,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -_cached_arch2triplet = None -_cached_triplet2arch = None +_cached_arch2tuple = None +_cached_tuple2arch = None _cached_cputable = None def _load_table(path): @@ -38,63 +38,65 @@ def _read_cputable(): _cached_cputable = _load_table('/usr/share/dpkg/cputable') return _cached_cputable -def _read_triplettable(): - global _cached_arch2triplet, _cached_triplet2arch - if _cached_arch2triplet is None or _cached_triplet2arch is None: - table = _load_table('/usr/share/dpkg/triplettable') - arch2triplet = dict() - triplet2arch = dict() +def _read_tupletable(): + global _cached_arch2tuple, _cached_tuple2arch + if _cached_arch2tuple is None or _cached_tuple2arch is None: + table = _load_table('/usr/share/dpkg/tupletable') + arch2tuple = dict() + tuple2arch = dict() for row in table: - debtriplet = row[0] + debtuple = row[0] debarch = row[1] - if '' in debtriplet: + if '' in debtuple: for r in _read_cputable(): cpu = r[0] - dt = debtriplet.replace('', cpu) + dt = debtuple.replace('', cpu) da = debarch.replace('', cpu) - arch2triplet[da] = dt - triplet2arch[dt] = da + arch2tuple[da] = dt + tuple2arch[dt] = da else: - arch2triplet[debarch] = debtriplet - triplet2arch[debtriplet] = debarch - _cached_arch2triplet = arch2triplet - _cached_triplet2arch = triplet2arch - return _cached_triplet2arch, _cached_arch2triplet + arch2tuple[debarch] = debtuple + tuple2arch[debtuple] = debarch + _cached_arch2tuple = arch2tuple + _cached_tuple2arch = tuple2arch + return _cached_tuple2arch, _cached_arch2tuple -def debwildcard_to_debtriplet(arch): - arch_tuple = arch.split('-', 2) +def debwildcard_to_debtuple(arch): + arch_tuple = arch.split('-', 3) if 'any' in arch_tuple: - if len(arch_tuple) == 3: + if len(arch_tuple) == 4: return arch_tuple + elif len(arch_tuple) == 3: + return ('any', arch_tuple[0], arch_tuple[1], arch_tuple[2]) elif len(arch_tuple) == 2: - return ('any', arch_tuple[0], arch_tuple[1]) + return ('any', 'any', arch_tuple[0], arch_tuple[1]) else: - return ('any', 'any', 'any') + return ('any', 'any', 'any', 'any') else: - return debarch_to_debtriplet(arch) + return debarch_to_debtuple(arch) -def debarch_to_debtriplet(arch): +def debarch_to_debtuple(arch): if (arch.startswith("linux-")): arch = arch[6:] - triplet = _read_triplettable()[1].get(arch) + tuple = _read_tupletable()[1].get(arch) - if triplet is None: + if tuple is None: return - return triplet.split('-', 2) + return tuple.split('-', 3) def match_architecture(real, alias): if alias == real or alias == "any": return True - real = debarch_to_debtriplet(real) - alias = debwildcard_to_debtriplet(alias) + real = debarch_to_debtuple(real) + alias = debwildcard_to_debtuple(alias) - if real is None or len(real) != 3 or alias is None or len(alias) != 3: + if real is None or len(real) != 4 or alias is None or len(alias) != 4: return False - for i in range(0,3): + for i in range(0,4): if (alias[i] != real[i] and alias[i] != "any"): return False return True diff --git a/run.py b/run.py index eb25c41..1da9f1f 100755 --- a/run.py +++ b/run.py @@ -17,15 +17,35 @@ import yaml import daklib_arch import debarch -os_list = [] +abi_from_abitable = [row[0] for row in debarch._load_table('/usr/share/dpkg/abitable')] +abi_from_ostable = [row[0].split('-')[0] for row in debarch._load_table('/usr/share/dpkg/ostable')] +abi_from_tupletable = [row[0].split('-')[0] for row in debarch._load_table('/usr/share/dpkg/tupletable')] +abi_wildcards = sorted(set(abi_from_abitable+abi_from_ostable+abi_from_tupletable+['any'])) -os_list = set([row[0].split('-')[1] for row in debarch._load_table('/usr/share/dpkg/ostable')]) +libc_from_ostable = [row[0].split('-')[1] for row in debarch._load_table('/usr/share/dpkg/ostable')] +libc_from_tupletable = [row[0].split('-')[1] for row in debarch._load_table('/usr/share/dpkg/tupletable')] +libc_wildcards = sorted(set(libc_from_ostable+libc_from_tupletable+['any'])) -cpu_list = set([row[0] for row in debarch._load_table('/usr/share/dpkg/cputable')]) +os_from_ostable = [row[0].split('-')[2] for row in debarch._load_table('/usr/share/dpkg/ostable')] +os_from_tupletable = [row[0].split('-')[2] for row in debarch._load_table('/usr/share/dpkg/tupletable')] +os_wildcards = sorted(set(os_from_ostable+os_from_tupletable+['any'])) -wildcard_list = [ o + "-" + c for o in os_list for c in cpu_list] +cpu_from_cputable = [row[0] for row in debarch._load_table('/usr/share/dpkg/cputable')] +cpu_from_tupletable = [row[0].split('-')[3] for row in debarch._load_table('/usr/share/dpkg/tupletable')] +cpu_wildcards = sorted(set(cpu_from_cputable+cpu_from_tupletable+['any'])-set([''])) -deb_list = subprocess.check_output(["dpkg-architecture", "-L"]).decode().split() +wildcard_list = list() + +for c in cpu_wildcards: + wildcard_list.append(c) + for o in os_wildcards: + wildcard_list.append(o+'-'+c) + for l in libc_wildcards: + wildcard_list.append(l+'-'+o+'-'+c) + for a in abi_wildcards: + wildcard_list.append(a+'-'+l+'-'+o+'-'+c) + +debarches = subprocess.check_output(["dpkg-architecture", "-L"]).decode().split() def dpkg_arch_matches(arch, wildcard): # environment must be empty or otherwise the DEB_HOST_ARCH environment @@ -52,7 +72,7 @@ Version: 0.invalid.0 data = yaml.load(data, Loader=yaml.CBaseLoader) return len(data['report']) == 1 -check_pairs = [ (d,w) for d in deb_list for w in wildcard_list ] +check_pairs = [ (d,w) for d in debarches for w in wildcard_list ] len_check_pairs = len(check_pairs) print("checking %d testcases"%len_check_pairs) @@ -68,7 +88,7 @@ for i,(d,w) in enumerate(check_pairs): deb_res = debarch.match_architecture(d,w) if dose_res != dpkg_res or dose_res != dak_res \ or dose_res != deb_res: - print("difference!") + print("\ndifference!") print("dose: %s matches %s: %s"%(w,d,dose_res)) print("dpkg: %s matches %s: %s"%(w,d,dpkg_res)) print("deb: %s matches %s: %s"%(w,d,deb_res))