162306a36Sopenharmony_ci#!/usr/bin/env python3 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only 362306a36Sopenharmony_ci 462306a36Sopenharmony_ciimport fnmatch 562306a36Sopenharmony_ciimport os 662306a36Sopenharmony_ciimport re 762306a36Sopenharmony_ciimport argparse 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cidef parse_of_declare_macros(data): 1162306a36Sopenharmony_ci """ Find all compatible strings in OF_DECLARE() style macros """ 1262306a36Sopenharmony_ci compat_list = [] 1362306a36Sopenharmony_ci # CPU_METHOD_OF_DECLARE does not have a compatible string 1462306a36Sopenharmony_ci for m in re.finditer(r'(?<!CPU_METHOD_)(IRQCHIP|OF)_(DECLARE|MATCH)(_DRIVER)?\(.*?\)', data): 1562306a36Sopenharmony_ci try: 1662306a36Sopenharmony_ci compat = re.search(r'"(.*?)"', m[0])[1] 1762306a36Sopenharmony_ci except: 1862306a36Sopenharmony_ci # Fails on compatible strings in #define, so just skip 1962306a36Sopenharmony_ci continue 2062306a36Sopenharmony_ci compat_list += [compat] 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci return compat_list 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cidef parse_of_device_id(data): 2662306a36Sopenharmony_ci """ Find all compatible strings in of_device_id structs """ 2762306a36Sopenharmony_ci compat_list = [] 2862306a36Sopenharmony_ci for m in re.finditer(r'of_device_id(\s+\S+)?\s+\S+\[\](\s+\S+)?\s*=\s*({.*?);', data): 2962306a36Sopenharmony_ci compat_list += re.findall(r'\.compatible\s+=\s+"(\S+)"', m[3]) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci return compat_list 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cidef parse_compatibles(file): 3562306a36Sopenharmony_ci with open(file, 'r', encoding='utf-8') as f: 3662306a36Sopenharmony_ci data = f.read().replace('\n', '') 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci compat_list = parse_of_declare_macros(data) 3962306a36Sopenharmony_ci compat_list += parse_of_device_id(data) 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci return compat_list 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cidef print_compat(filename, compatibles): 4462306a36Sopenharmony_ci if not compatibles: 4562306a36Sopenharmony_ci return 4662306a36Sopenharmony_ci if show_filename: 4762306a36Sopenharmony_ci compat_str = ' '.join(compatibles) 4862306a36Sopenharmony_ci print(filename + ": compatible(s): " + compat_str) 4962306a36Sopenharmony_ci else: 5062306a36Sopenharmony_ci print(*compatibles, sep='\n') 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cidef glob_without_symlinks(root, glob): 5362306a36Sopenharmony_ci for path, dirs, files in os.walk(root): 5462306a36Sopenharmony_ci # Ignore hidden directories 5562306a36Sopenharmony_ci for d in dirs: 5662306a36Sopenharmony_ci if fnmatch.fnmatch(d, ".*"): 5762306a36Sopenharmony_ci dirs.remove(d) 5862306a36Sopenharmony_ci for f in files: 5962306a36Sopenharmony_ci if fnmatch.fnmatch(f, glob): 6062306a36Sopenharmony_ci yield os.path.join(path, f) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cidef files_to_parse(path_args): 6362306a36Sopenharmony_ci for f in path_args: 6462306a36Sopenharmony_ci if os.path.isdir(f): 6562306a36Sopenharmony_ci for filename in glob_without_symlinks(f, "*.c"): 6662306a36Sopenharmony_ci yield filename 6762306a36Sopenharmony_ci else: 6862306a36Sopenharmony_ci yield f 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cishow_filename = False 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciif __name__ == "__main__": 7362306a36Sopenharmony_ci ap = argparse.ArgumentParser() 7462306a36Sopenharmony_ci ap.add_argument("cfile", type=str, nargs='*', help="C source files or directories to parse") 7562306a36Sopenharmony_ci ap.add_argument('-H', '--with-filename', help="Print filename with compatibles", action="store_true") 7662306a36Sopenharmony_ci args = ap.parse_args() 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci show_filename = args.with_filename 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci for f in files_to_parse(args.cfile): 8162306a36Sopenharmony_ci compat_list = parse_compatibles(f) 8262306a36Sopenharmony_ci print_compat(f, compat_list) 83