1*6fa2df46SAndroid Build Coastguard Worker#!/bin/env python3 2*6fa2df46SAndroid Build Coastguard Worker 3*6fa2df46SAndroid Build Coastguard Worker# Copyright (C) 2024 The Android Open Source Project 4*6fa2df46SAndroid Build Coastguard Worker# 5*6fa2df46SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*6fa2df46SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*6fa2df46SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*6fa2df46SAndroid Build Coastguard Worker# 9*6fa2df46SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*6fa2df46SAndroid Build Coastguard Worker# 11*6fa2df46SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*6fa2df46SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*6fa2df46SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*6fa2df46SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*6fa2df46SAndroid Build Coastguard Worker# limitations under the License. 16*6fa2df46SAndroid Build Coastguard Worker 17*6fa2df46SAndroid Build Coastguard Workerimport argparse 18*6fa2df46SAndroid Build Coastguard Worker 19*6fa2df46SAndroid Build Coastguard Worker 20*6fa2df46SAndroid Build Coastguard Workerdef fetch_arguments(): 21*6fa2df46SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 22*6fa2df46SAndroid Build Coastguard Worker prog="ditto2cpp", 23*6fa2df46SAndroid Build Coastguard Worker description="Translate .ditto file to C++ source files to embed in the benchmark." 24*6fa2df46SAndroid Build Coastguard Worker ) 25*6fa2df46SAndroid Build Coastguard Worker parser.add_argument("-o", "--output", required=True, help="Output file", 26*6fa2df46SAndroid Build Coastguard Worker type=str) 27*6fa2df46SAndroid Build Coastguard Worker parser.add_argument("-s", "--sources", required=True, nargs='+', 28*6fa2df46SAndroid Build Coastguard Worker help="Source .ditto files", type=str) 29*6fa2df46SAndroid Build Coastguard Worker parser.add_argument("-v", "--verbose", help="Verbose output", 30*6fa2df46SAndroid Build Coastguard Worker action='store_true') 31*6fa2df46SAndroid Build Coastguard Worker args = parser.parse_args() 32*6fa2df46SAndroid Build Coastguard Worker 33*6fa2df46SAndroid Build Coastguard Worker if args.verbose: 34*6fa2df46SAndroid Build Coastguard Worker print('From: "{}"'.format(args.sources)) 35*6fa2df46SAndroid Build Coastguard Worker print('Output: "{}"'.format(args.output)) 36*6fa2df46SAndroid Build Coastguard Worker 37*6fa2df46SAndroid Build Coastguard Worker return args 38*6fa2df46SAndroid Build Coastguard Worker 39*6fa2df46SAndroid Build Coastguard Worker 40*6fa2df46SAndroid Build Coastguard Workerdef compute_common_prefix(arr): 41*6fa2df46SAndroid Build Coastguard Worker result = arr[0] 42*6fa2df46SAndroid Build Coastguard Worker length = len(result) 43*6fa2df46SAndroid Build Coastguard Worker 44*6fa2df46SAndroid Build Coastguard Worker # Iterate for the rest of the elements in the array 45*6fa2df46SAndroid Build Coastguard Worker for i in range(1, len(arr)): 46*6fa2df46SAndroid Build Coastguard Worker # Find the index of result in the current string 47*6fa2df46SAndroid Build Coastguard Worker while arr[i].find(result) != 0: 48*6fa2df46SAndroid Build Coastguard Worker # Update the matched substring prefix 49*6fa2df46SAndroid Build Coastguard Worker result = result[:length - 1] 50*6fa2df46SAndroid Build Coastguard Worker length -= 1 51*6fa2df46SAndroid Build Coastguard Worker 52*6fa2df46SAndroid Build Coastguard Worker # Check for an empty case and return if true 53*6fa2df46SAndroid Build Coastguard Worker if not result: 54*6fa2df46SAndroid Build Coastguard Worker raise Exception("No results") 55*6fa2df46SAndroid Build Coastguard Worker return result 56*6fa2df46SAndroid Build Coastguard Worker 57*6fa2df46SAndroid Build Coastguard Worker 58*6fa2df46SAndroid Build Coastguard Workerdef generate_benchmark_source(output, sources): 59*6fa2df46SAndroid Build Coastguard Worker common_prefix = compute_common_prefix(sources) 60*6fa2df46SAndroid Build Coastguard Worker last_slash_in_prefix = 0 61*6fa2df46SAndroid Build Coastguard Worker try: 62*6fa2df46SAndroid Build Coastguard Worker last_slash_in_prefix = len(common_prefix) - common_prefix[::-1].index('/') 63*6fa2df46SAndroid Build Coastguard Worker except ValueError: 64*6fa2df46SAndroid Build Coastguard Worker # This happens when '/' cannot be found in `common_prefix` 65*6fa2df46SAndroid Build Coastguard Worker pass 66*6fa2df46SAndroid Build Coastguard Worker prefix_length = min(len(common_prefix), last_slash_in_prefix) 67*6fa2df46SAndroid Build Coastguard Worker suffix_length = len(".ditto") 68*6fa2df46SAndroid Build Coastguard Worker 69*6fa2df46SAndroid Build Coastguard Worker file_header = ''' 70*6fa2df46SAndroid Build Coastguard Worker #include <ditto/embedded_benchmarks.h> 71*6fa2df46SAndroid Build Coastguard Worker const std::map<std::string, std::string> ditto_static_config = { 72*6fa2df46SAndroid Build Coastguard Worker ''' 73*6fa2df46SAndroid Build Coastguard Worker file_footer = ''' 74*6fa2df46SAndroid Build Coastguard Worker }; 75*6fa2df46SAndroid Build Coastguard Worker ''' 76*6fa2df46SAndroid Build Coastguard Worker with open(output, 'w') as fo: 77*6fa2df46SAndroid Build Coastguard Worker fo.write(file_header) 78*6fa2df46SAndroid Build Coastguard Worker for fi_path in sources: 79*6fa2df46SAndroid Build Coastguard Worker fi_name = fi_path[prefix_length:-suffix_length] 80*6fa2df46SAndroid Build Coastguard Worker with open(fi_path, 'r') as fi: 81*6fa2df46SAndroid Build Coastguard Worker fo.write('\t') 82*6fa2df46SAndroid Build Coastguard Worker fo.write('{{"{}", "{}"}},'.format( 83*6fa2df46SAndroid Build Coastguard Worker fi_name, 84*6fa2df46SAndroid Build Coastguard Worker fi.read().replace('\n', '').replace('"', '\\"') 85*6fa2df46SAndroid Build Coastguard Worker )) 86*6fa2df46SAndroid Build Coastguard Worker fo.write('\n') 87*6fa2df46SAndroid Build Coastguard Worker fo.write(file_footer) 88*6fa2df46SAndroid Build Coastguard Worker 89*6fa2df46SAndroid Build Coastguard Worker 90*6fa2df46SAndroid Build Coastguard Workerif __name__ == '__main__': 91*6fa2df46SAndroid Build Coastguard Worker args = fetch_arguments() 92*6fa2df46SAndroid Build Coastguard Worker 93*6fa2df46SAndroid Build Coastguard Worker generate_benchmark_source(args.output, args.sources) 94*6fa2df46SAndroid Build Coastguard Worker 95*6fa2df46SAndroid Build Coastguard Worker if args.verbose: 96*6fa2df46SAndroid Build Coastguard Worker print("Output file content:") 97*6fa2df46SAndroid Build Coastguard Worker print('-' * 32) 98*6fa2df46SAndroid Build Coastguard Worker with open(args.output, 'r') as fo: 99*6fa2df46SAndroid Build Coastguard Worker print(fo.read()) 100*6fa2df46SAndroid Build Coastguard Worker print('-' * 32) 101