18157b447Smrg#!/usr/bin/env python3 21c606da7Smrg 31c606da7Smrgimport argparse 41c606da7Smrgimport re 58157b447Smrgimport sys 68157b447Smrgfrom pathlib import Path 71c606da7Smrg 81c606da7Smrg 91c606da7Smrgclass Layout(object): 101c606da7Smrg def __init__(self, layout, variant=None): 111c606da7Smrg self.layout = layout 121c606da7Smrg self.variant = variant 131c606da7Smrg if '(' in layout: 141c606da7Smrg assert variant is None 151c606da7Smrg # parse a layout(variant) string 161c606da7Smrg match = re.match(r'([^(]+)\(([^)]+)\)', layout) 178157b447Smrg self.layout = match.groups()[0] 188157b447Smrg self.variant = match.groups()[1] 191c606da7Smrg 201c606da7Smrg def __str__(self): 211c606da7Smrg if self.variant: 221c606da7Smrg return '{}({})'.format(self.layout, self.variant) 231c606da7Smrg else: 241c606da7Smrg return '{}'.format(self.layout) 251c606da7Smrg 261c606da7Smrg 271c606da7Smrgdef read_file(path): 281c606da7Smrg '''Returns a list of two-layout tuples [(layout1, layout2), ...]''' 291c606da7Smrg 301c606da7Smrg # This parses both input files, one with two elements, one with four elements, 311c606da7Smrg # all separated by tabs 321c606da7Smrg pattern = re.compile(r'([^\t]+)\s+([^\t]+)\s*([^\t]*)\s*([^\t]*)') 331c606da7Smrg 341c606da7Smrg layouts = [] 351c606da7Smrg for line in open(path): 361c606da7Smrg match = re.match(pattern, line.strip()) 371c606da7Smrg groups = [g for g in match.groups() if g] # drop empty groups 381c606da7Smrg if len(groups) == 2: 391c606da7Smrg l1 = Layout(groups[0]) 401c606da7Smrg l2 = Layout(groups[1]) 411c606da7Smrg else: 421c606da7Smrg l1 = Layout(groups[0], groups[1]) 431c606da7Smrg l2 = Layout(groups[2], groups[3]) 441c606da7Smrg layouts.append((l1, l2)) 451c606da7Smrg return layouts 461c606da7Smrg 471c606da7Smrg 481c606da7Smrg# ml_s 491c606da7Smrgdef write_fixed_layout(dest, mappings, write_header): 501c606da7Smrg if write_header: 511c606da7Smrg dest.write('! model layout = symbols\n') 521c606da7Smrg for l1, l2 in mappings: 531c606da7Smrg dest.write(' * {} = pc+{}\n'.format(l1, l2)) 541c606da7Smrg 551c606da7Smrg 561c606da7Smrg# mln_s 571c606da7Smrgdef write_layout_n(dest, mappings, number, write_header): 581c606da7Smrg if write_header: 591c606da7Smrg dest.write('! model layout[{}] = symbols\n'.format(number)) 601c606da7Smrg 611c606da7Smrg # symbols is one of 621c606da7Smrg # +layout(variant):2 ... where the map-to-layout has a proper variant 631c606da7Smrg # +layout%(v[2]):2 ... where the map-to-layout does not have a variant 641c606da7Smrg # and where the number is 1, we have a base and drop the suffix, i.e. 651c606da7Smrg # the above becomes 661c606da7Smrg # pc+layout(variant) 671c606da7Smrg # pc+layout%(v[1]) 681c606da7Smrg 691c606da7Smrg base = 'pc' if number == 1 else '' 701c606da7Smrg suffix = '' if number == 1 else ':{}'.format(number) 711c606da7Smrg 721c606da7Smrg for l1, l2 in mappings: 731c606da7Smrg second_layout = str(l2) if l2.variant else '{}%(v[{}])'.format(l2.layout, number) 741c606da7Smrg dest.write(' * {} = {}+{}{}\n'.format(l1, base, second_layout, suffix)) 751c606da7Smrg 761c606da7Smrg 771c606da7Smrg# mlv_s 781c606da7Smrgdef write_fixed_layout_variant(dest, mappings, write_header): 791c606da7Smrg if write_header: 801c606da7Smrg dest.write('! model layout variant = symbols\n') 811c606da7Smrg for l1, l2 in mappings: 821c606da7Smrg dest.write(' * {} {} = pc+{}\n'.format(l1.layout, l1.variant, l2)) 831c606da7Smrg 841c606da7Smrg 851c606da7Smrg# mlnvn_s 861c606da7Smrgdef write_layout_n_variant_n(dest, mappings, number, write_header): 871c606da7Smrg if write_header: 881c606da7Smrg dest.write('! model layout[{}] variant[{}] = symbols\n'.format(number, number)) 891c606da7Smrg 901c606da7Smrg # symbols is 911c606da7Smrg # +layout(variant):2 921c606da7Smrg # and where the number is 1, we have a base and drop the suffix, i.e. 931c606da7Smrg # the above becomes 941c606da7Smrg # pc+layout(variant) 951c606da7Smrg # This part is only executed for the variantMappings.lst 961c606da7Smrg 971c606da7Smrg base = 'pc' if number == 1 else '' 981c606da7Smrg suffix = '' if number == 1 else ':{}'.format(number) 991c606da7Smrg 1001c606da7Smrg for l1, l2 in mappings: 1011c606da7Smrg second_layout = str(l2) if l2.variant else '{}%(v[{}])'.format(l2.layout, number) 1021c606da7Smrg dest.write(' * {} {} = {}+{}{}\n'.format(l1.layout, l1.variant, base, second_layout, suffix)) 1031c606da7Smrg 1041c606da7Smrg 1051c606da7Smrgdef map_variant(dest, files, want='mls', number=None): 1068157b447Smrg if number == 0: 1078157b447Smrg number = None 1088157b447Smrg 1091c606da7Smrg for idx, f in enumerate(files): 1101c606da7Smrg write_header = idx == 0 1111c606da7Smrg 1121c606da7Smrg mappings = read_file(f) 1131c606da7Smrg if want == 'mls': 1141c606da7Smrg if number is None: 1151c606da7Smrg write_fixed_layout(dest, mappings, write_header) 1161c606da7Smrg else: 1171c606da7Smrg write_layout_n(dest, mappings, number, write_header) 1181c606da7Smrg elif want == 'mlvs': 1191c606da7Smrg if number is None: 1201c606da7Smrg write_fixed_layout_variant(dest, mappings, write_header) 1211c606da7Smrg else: 1221c606da7Smrg write_layout_n_variant_n(dest, mappings, number, write_header) 1231c606da7Smrg else: 1241c606da7Smrg raise NotImplementedError() 1251c606da7Smrg 1261c606da7Smrg 1271c606da7Smrgif __name__ == '__main__': 1281c606da7Smrg parser = argparse.ArgumentParser('variant mapping script') 1291c606da7Smrg parser.add_argument('--want', type=str, 1301c606da7Smrg choices=['mls', 'mlvs']) 1311c606da7Smrg parser.add_argument('--number', type=int, default=None) 1321c606da7Smrg 1331c606da7Smrg parser.add_argument('dest', type=str) 1341c606da7Smrg parser.add_argument('files', nargs='+', type=str) 1351c606da7Smrg ns = parser.parse_args() 1361c606da7Smrg 1378157b447Smrg dest = None 1388157b447Smrg if ns.dest == '-': 1398157b447Smrg dest = sys.stdout 1408157b447Smrg 1418157b447Smrg with dest or open(ns.dest, 'w') as fd: 1421c606da7Smrg map_variant(fd, ns.files, ns.want, ns.number) 143