1#!/usr/bin/env python3 2#coding: utf-8 3""" 4Copyright (c) 2024 Huawei Device Co., Ltd. 5Licensed under the Apache License, Version 2.0 (the "License"); 6you may not use this file except in compliance with the License. 7You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11Unless required by applicable law or agreed to in writing, software 12distributed under the License is distributed on an "AS IS" BASIS, 13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14See the License for the specific language governing permissions and 15limitations under the License. 16 17Description: run script 18 input: input file 19 output: output file 20 prefix: prefix 21""" 22 23import os 24import sys 25import argparse 26 27replace_config1 = [ 28 {"id": "REPLACE_FUNC_FOO1", "start": 0, "end": 31608}, 29 {"id": "REPLACE_FUNC_FOO2", "start": 31609, "end": 65535}, 30] 31replace_config2 = [ 32 {"id": "REPLACE_FUNC_FOO1", "start": 0, "end": 65488}, 33 {"id": "REPLACE_FUNC_FOO2", "start": 65489, "end": 65535}, 34] 35replace_config3 = [ 36 {"id": "REPLACE_FUNC_FOO1", "start": 0, "end": 65488}, 37 {"id": "REPLACE_FUNC_FOO2", "start": 65489, "end": 65536}, 38] 39replace_config4 = [ 40 {"id": "REPLACE_FUNC_FOO1", "start": 35004, "end": 40153}, 41 {"id": "REPLACE_FUNC_FOO2", "start": 1, "end": 34999, "isFunc": True, "msg": "base"}, 42] 43replace_config5 = [ 44 {"id": "REPLACE_FUNC_FOO1", "start": 35004, "end": 40153}, 45 {"id": "REPLACE_FUNC_FOO2", "start": 1, "end": 34999, "isFunc": True, "msg": "patch"}, 46] 47 48AOT_MULTI_CONSTANTPOOL_TEST_PATH = "ets_runtime/test/aottest/aot_multi_constantpool_test/" 49 50file_list = [ 51 { 52 "file_name": "ets_runtime/test/quickfix/multi_funcconstpool/base_modify.js", 53 "replace_config": replace_config1, 54 }, 55 { 56 "file_name": "ets_runtime/test/quickfix/multi_funcconstpool/base.js", 57 "replace_config": replace_config1, 58 }, 59 { 60 "file_name": "ets_runtime/test/quickfix/multi_funccallconstpool/base_modify.js", 61 "replace_config": replace_config1, 62 }, 63 { 64 "file_name": "ets_runtime/test/quickfix/multi_funccallconstpool/base.js", 65 "replace_config": replace_config1, 66 }, 67 { 68 "file_name": "ets_runtime/test/quickfix/multi_constructorconstpool/base_modify.js", 69 "replace_config": replace_config1, 70 }, 71 { 72 "file_name": "ets_runtime/test/quickfix/multi_constructorconstpool/base.js", 73 "replace_config": replace_config1, 74 }, 75 { 76 "file_name": "ets_runtime/test/quickfix/multi_closureconstpool/base_modify.js", 77 "replace_config": replace_config3, 78 }, 79 { 80 "file_name": "ets_runtime/test/quickfix/multi_closureconstpool/base.js", 81 "replace_config": replace_config3, 82 }, 83 { 84 "file_name": "ets_runtime/test/quickfix/multi_classconstpool/base_modify.js", 85 "replace_config": replace_config2, 86 }, 87 { 88 "file_name": "ets_runtime/test/quickfix/multi_classconstpool/base.js", 89 "replace_config": replace_config2, 90 }, 91 { 92 "file_name": "ets_runtime/test/quickfix/multiconstpool_multifunc/base.js", 93 "replace_config": replace_config4, 94 }, 95 { 96 "file_name": "ets_runtime/test/quickfix/multiconstpool_multifunc/base_modify.js", 97 "replace_config": replace_config5, 98 }, 99 { 100 "file_name": "ets_runtime/test/moduletest/multiconstpoolobj/multiconstpoolobj.js", 101 "replace_config": replace_config2, 102 }, 103 { 104 "file_name": "ets_runtime/test/moduletest/multiconstpoolfunc/multiconstpoolfunc.js", 105 "replace_config": replace_config2, 106 }, 107 { 108 "file_name": "ets_runtime/test/moduletest/multiconstpoolconstructor/multiconstpoolconstructor.js", 109 "replace_config": replace_config2, 110 }, 111 { 112 "file_name": "ets_runtime/test/moduletest/multiconstpoolclass/multiconstpoolclass.js", 113 "replace_config": replace_config2, 114 }, 115 { 116 "file_name": "ets_runtime/test/moduletest/multiconstpoolarray/multiconstpoolarray.js", 117 "replace_config": replace_config2, 118 }, 119 { 120 "file_name": AOT_MULTI_CONSTANTPOOL_TEST_PATH 121 + "multi_constantpool_func/multi_constantpool_func.ts", 122 "replace_config": replace_config1, 123 }, 124 { 125 "file_name": AOT_MULTI_CONSTANTPOOL_TEST_PATH 126 + "multi_constantpool_constructor/multi_constantpool_constructor.ts", 127 "replace_config": replace_config2, 128 }, 129 { 130 "file_name": AOT_MULTI_CONSTANTPOOL_TEST_PATH 131 + "multi_constantpool_class/multi_constantpool_class.ts", 132 "replace_config": replace_config2, 133 }, 134 { 135 "file_name": AOT_MULTI_CONSTANTPOOL_TEST_PATH 136 + "multi_constantpool_funccall/multi_constantpool_funccall.ts", 137 "replace_config": replace_config1, 138 }, 139 { 140 "file_name": AOT_MULTI_CONSTANTPOOL_TEST_PATH 141 + "multi_constantpool_closure/multi_constantpool_closure.ts", 142 "replace_config": replace_config3, 143 }, 144] 145 146 147def generate_var(var_begin, var_end): 148 str_var_list = [] 149 for i in range(var_begin, var_end + 1): 150 str_var_list.append('var a{0} = "{1}";'.format(i, i)) 151 if (i + 1) % 6 == 0: 152 str_var_list.append("\n") 153 return ''.join(str_var_list) 154 155 156def generate_funcs(var_begin, var_end, msg): 157 str_func_list = [] 158 for i in range(var_begin, var_end + 1): 159 str_func_list.append('function foo{0}()'.format(i)) 160 str_func_list.append('{\n\t') 161 str_func_list.append('var a{0} = "{1}";\n\tprint("{2} foo{3}")\n'.format(i, i, msg, i)) 162 str_func_list.append('}\n') 163 return ''.join(str_func_list) 164 165 166def read_file_content(input_file): 167 input_fd = os.open(input_file, os.O_RDONLY, 0o755) 168 with os.fdopen(input_fd, 'r') as fp: 169 return fp.read() 170 171 172def write_file_content(output_file, data): 173 output_fd = os.open(output_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o755) 174 if os.path.exists(output_file): 175 with os.fdopen(output_fd, 'w') as fp: 176 fp.write(data) 177 178 179def replace_in_data(data, replace_config): 180 for cfg in replace_config: 181 if cfg["id"] in data: 182 if "isFunc" in cfg: 183 str_func = generate_funcs(cfg["start"], cfg["end"], cfg["msg"]) 184 data = data.replace(cfg["id"], str_func) 185 else: 186 str_var = generate_var(cfg["start"], cfg["end"]) 187 data = data.replace(cfg["id"], str_var) 188 return data 189 190 191def replace_js(input_file, output_file): 192 for file in file_list: 193 file_name = file.get("file_name") 194 if not input_file.endswith(file_name): 195 continue 196 data = read_file_content(input_file) 197 replace_config = file.get("replace_config") 198 data = replace_in_data(data, replace_config) 199 write_file_content(output_file, data) 200 return output_file 201 return None 202 203 204def is_file_in_list(file_path): 205 input_dir_path = ( 206 os.path.dirname(file_path) 207 if os.path.isfile(file_path) 208 else file_path 209 ) 210 211 for item in file_list: 212 file_name = item.get("file_name") 213 list_dir_path = os.path.dirname(file_name) 214 if list_dir_path in input_dir_path: 215 return True 216 return False 217 218 219def process_with_prefix(input_file, output_file, prefix): 220 input_fd = os.open(input_file, os.O_RDONLY, 0o755) 221 output_fd = os.open(output_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o755) 222 with os.fdopen(input_fd, 'r') as inputfp, os.fdopen(output_fd, 'w') as outputfp: 223 for line in inputfp: 224 outputfp.write(prefix + line) 225 226 227def handle_files(input_file, output_file, prefix): 228 input_fd = os.open(input_file, os.O_RDONLY, 0o755) 229 output_fd = os.open(output_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o755) 230 output_file_dir = os.path.dirname(output_file) 231 232 with os.fdopen(input_fd, "r") as fp, os.fdopen(output_fd, "w") as outputfp: 233 lines = fp.readlines() 234 for line in lines: 235 ll = line.split(";") 236 original_js_filename = os.path.basename(ll[0]) 237 js_fn = replace_js(prefix + ll[0], os.path.join(output_file_dir, original_js_filename)) 238 if js_fn and os.path.exists(js_fn): 239 ll[0] = js_fn 240 else: 241 ll[0] = prefix + ll[0] 242 outputfp.write(";".join(ll)) 243 244 245def replace_merge_file(input_file, output_file, prefix): 246 if input_file.endswith(("base.txt", "patch.txt")) and is_file_in_list(prefix): 247 handle_files(input_file, output_file, prefix) 248 else: 249 process_with_prefix(input_file, output_file, prefix) 250 251 252def replace_var(input_file, output_file, prefix): 253 if prefix: 254 replace_merge_file(input_file, output_file, prefix) 255 else: 256 replace_js(input_file, output_file) 257 258 259def main(): 260 parser = argparse.ArgumentParser() 261 parser.add_argument("--input", type=str, required=True) 262 parser.add_argument("--output", type=str, required=True) 263 parser.add_argument("--prefix", type=str) 264 265 args = parser.parse_args() 266 replace_var(os.path.abspath(args.input), args.output, args.prefix) 267 268 269if __name__ == "__main__": 270 sys.exit(main()) 271