13340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento#!/usr/bin/python3 23340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento""" Synchronizes enums and their comments from the NeuralNetworks.h to types.hal 33340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 43340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoWorkflow: 53340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - Don't try to make other changes to types.hal in the same branch, as this 63340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento will check out and overwrite files 73340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - Edit NeuralNetworks.h 83340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - run sync_enums_to_hal.py 93340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - can be run from anywhere, but ANDROID_BUILD_TOP must be set 103340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - this resets 1.(0|1)/types.hal to last commit (so you can run 113340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento the script multiple times with changes to it in-between), and 123340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - overwrites types.hal in-place 133340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - Check the output (git diff) 143340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - Recreate hashes 153340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - commit and upload for review 163340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 173340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoNote: 183340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoThis is somewhat brittle in terms of ordering and formatting of the 193340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentorelevant files. It's the author's opinion that it's not worth spending a lot of 203340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentotime upfront coming up with better mechanisms, but to improve it when needed. 213340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoFor example, currently Operations have differences between 1.0 and 1.1, 223340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentobut Operands do not, so the script is explicit rather than generic. 233340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 243340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoThere are asserts in the code to make sure the expectations on the ordering and 253340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoformatting of the headers are met, so this should fail rather than produce 263340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentocompletely unexpected output. 273340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 283340f8bea2913ee5f4d76193c11f1068b6582770Mika RaentoThe alternative would be to add explicit section markers to the files. 293340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 303340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento""" 313340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 323340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoimport os 333340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoimport re 343340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoimport subprocess 353340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 363340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoclass HeaderReader(object): 373340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ Simple base class facilitates reading a file into sections and writing it 383340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento back out 393340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ 403340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def __init__(self): 413340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections = [] 423340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.current = -1 433340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 443340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 453340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def put_back(self, no_of_lines=1): 463340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert not self.sections[self.current] 473340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento for i in range(0, no_of_lines): 483340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = self.sections[self.current - 1].pop() 493340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections[self.current].insert(0, line) 503340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 513340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def next_section(self): 523340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.current = self.current + 1 533340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections.append([]) 543340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 553340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def get_contents(self): 563340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento return "".join([ "".join(s) for s in self.sections]) 573340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 583340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def get_section(self, which): 593340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento return "".join(self.sections[which]) 603340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 613340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def handle_line(self, line): 623340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert False 633340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 643340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def read(self, filename): 653340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == 0 663340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.filename = filename 673340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento with open(filename) as f: 683340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento lines = f.readlines() 693340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento for line in lines: 703340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections[self.current].append(line) 713340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if self.current == self.REST: 723340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento continue 733340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.handle_line(line) 743340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.REST 753340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 763340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def write(self): 773340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento with open(self.filename, "w") as f: 783340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento f.write(self.get_contents()) 793340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 803340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoclass Types10Reader(HeaderReader): 813340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ Reader for 1.0 types.hal 823340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 833340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento The structure of the file is: 843340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - preamble 853340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - enum OperandType ... { 863340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERAND section > 873340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OEM operands 883340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento }; 893340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - comments 903340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - enum OperationType ... { 913340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERATION section > 923340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OEM operarions 933340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento }; 943340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - rest 953340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ 963340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento BEFORE_OPERAND = 0 973340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERAND = 1 983340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento BEFORE_OPERATION = 2 993340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERATION = 3 1003340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento REST = 4 1013340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1023340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def __init__(self): 1033340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento super(Types10Reader, self).__init__() 1043340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.read("hardware/interfaces/neuralnetworks/1.0/types.hal") 1053340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1063340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def handle_line(self, line): 1073340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if "enum OperandType" in line: 1083340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.BEFORE_OPERAND 1093340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1103340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif "enum OperationType" in line: 1113340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.BEFORE_OPERATION 1123340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1133340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif "OEM" in line and self.current == self.OPERAND: 1143340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1153340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back(2) 1163340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif "OEM specific" in line and self.current == self.OPERATION: 1173340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1183340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back(2) 1193340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1203340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoclass Types11Reader(HeaderReader): 1213340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ Reader for 1.1 types.hal 1223340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1233340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento The structure of the file is: 1243340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - preamble 1253340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - enum OperationType ... { 1263340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERATION section > 1273340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento }; 1283340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - rest 1293340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ 1303340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1313340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento BEFORE_OPERATION = 0 1323340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERATION = 1 1333340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento REST = 2 1343340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1353340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def __init__(self): 1363340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento super(Types11Reader, self).__init__() 1373340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.read("hardware/interfaces/neuralnetworks/1.1/types.hal") 1383340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1393340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def handle_line(self, line): 1403340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if "enum OperationType" in line: 1413340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.BEFORE_OPERATION 1423340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1433340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # there is more content after the enums we are interested in so 1443340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # it cannot be the last line, can match with \n 1453340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif line == "};\n": 1463340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1473340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back() 1483340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1493340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoclass NeuralNetworksReader(HeaderReader): 1503340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ Reader for NeuralNetworks.h 1513340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1523340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento The structure of the file is: 1533340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - preamble 1543340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - typedef enum { 1553340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERAND section > 1563340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento } OperandCode; 1573340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - comments 1583340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - typedef enum { 1593340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERATION_V10 section > 1603340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento // TODO: change to __ANDROID_API__ >= __ANDROID_API_P__ once available. 1613340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento #if __ANDROID_API__ > __ANDROID_API_O_MR1__ 1623340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento < this becomes the OPERATION_V11 section > 1633340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento #endif 1643340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento }; 1653340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento - rest 1663340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento """ 1673340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1683340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento BEFORE_OPERAND = 0 1693340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERAND = 1 1703340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento BEFORE_OPERATION = 2 1713340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERATION_V10 = 3 1723340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento OPERATION_V11 = 4 1733340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento REST = 5 1743340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1753340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def __init__(self): 1763340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento super(NeuralNetworksReader, self).__init__() 1773340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.read("frameworks/ml/nn/runtime/include/NeuralNetworks.h") 1783340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1793340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def handle_line(self, line): 1803340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if line == "typedef enum {\n": 1813340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1823340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif line == "} OperandCode;\n": 1833340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.OPERAND 1843340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1853340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back() 1863340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif self.current == self.OPERATION_V10 and "#if __ANDROID_API__ >" in line: 1873340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1883340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Get rid of the API divider altogether 1893340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back(2) 1903340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections[self.current] = [] 1913340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento elif line == "} OperationCode;\n": 1923340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert self.current == self.OPERATION_V11 1933340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.next_section() 1943340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.put_back() 1953340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Get rid of API divider #endif 1963340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento self.sections[self.OPERATION_V11].pop() 1973340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1983340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 1993340f8bea2913ee5f4d76193c11f1068b6582770Mika Raentoif __name__ == '__main__': 2003340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Reset 2013340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento assert os.environ["ANDROID_BUILD_TOP"] 2023340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento os.chdir(os.environ["ANDROID_BUILD_TOP"]) 2033340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento subprocess.run( 2043340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento "cd hardware/interfaces/neuralnetworks && git checkout */types.hal", 2053340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento shell=True) 2063340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 2073340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Read existing contents 2083340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types10 = Types10Reader() 2093340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types11 = Types11Reader() 2103340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento nn = NeuralNetworksReader() 2113340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 2123340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Rewrite from header syntax to HAL and replace types.hal contents 2133340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento operand = [] 2143340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento for line in nn.sections[nn.OPERAND]: 2153340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("ANEURALNETWORKS_", "") 2163340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento operand.append(line) 2173340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types10.sections[types10.OPERAND] = operand 2183340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento def rewrite_operation(from_nn): 2193340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento hal = [] 2203340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento for line in from_nn: 2213340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if "TODO" in line: 2223340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento continue 2233340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 2243340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Match multiline comment style 2253340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento if re.match("^ */\*\* \w.*[^/]$", line): 2263340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento hal.append(" /**\n") 2273340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("/** ", " * ") 2283340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Match naming changes in HAL vs framework 229f1a4694344c8acf2b157724ddf7df6ce2d1ac7bbMichael Butler line = line.replace("@link OperandCode", "@link OperandType") 2303340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("@link ANEURALNETWORKS_", "@link OperandType::") 2313340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("ANEURALNETWORKS_", "") 2323340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("FuseCode", "FusedActivationFunc") 2333340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # PaddingCode is not part of HAL, rewrite 2343340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento line = line.replace("{@link PaddingCode} values", 2353340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento "following values: {0 (NONE), 1 (SAME), 2 (VALID)}") 2363340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento hal.append(line) 2373340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento return hal 2383340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types10.sections[types10.OPERATION] = rewrite_operation(nn.sections[nn.OPERATION_V10]) 2393340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types11.sections[types11.OPERATION] = rewrite_operation(nn.sections[nn.OPERATION_V11]) 2403340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 2413340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento # Write synced contents 2423340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types10.write() 2433340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento types11.write() 2443340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento 2453340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("") 2463340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("The files") 2473340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print(" " + types10.filename + " and") 2483340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print(" " + types11.filename) 2493340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("have been rewritten") 2503340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("") 2513340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("Check that the change matches your expectations and regenerate the hashes") 2523340f8bea2913ee5f4d76193c11f1068b6582770Mika Raento print("") 253