1b6acf807SRob Herring#!/usr/bin/env python3 2b6acf807SRob Herring# SPDX-License-Identifier: GPL-2.0-only 3b6acf807SRob Herring 4*7cb7001eSNícolas F. R. A. Pradoimport fnmatch 5b6acf807SRob Herringimport os 6b6acf807SRob Herringimport re 7b6acf807SRob Herringimport argparse 8b6acf807SRob Herring 9b6acf807SRob Herring 10b6acf807SRob Herringdef parse_of_declare_macros(data): 11b6acf807SRob Herring """ Find all compatible strings in OF_DECLARE() style macros """ 12b6acf807SRob Herring compat_list = [] 13b6acf807SRob Herring # CPU_METHOD_OF_DECLARE does not have a compatible string 14b6acf807SRob Herring for m in re.finditer(r'(?<!CPU_METHOD_)(IRQCHIP|OF)_(DECLARE|MATCH)(_DRIVER)?\(.*?\)', data): 15b6acf807SRob Herring try: 16b6acf807SRob Herring compat = re.search(r'"(.*?)"', m[0])[1] 17b6acf807SRob Herring except: 18b6acf807SRob Herring # Fails on compatible strings in #define, so just skip 19b6acf807SRob Herring continue 20b6acf807SRob Herring compat_list += [compat] 21b6acf807SRob Herring 22b6acf807SRob Herring return compat_list 23b6acf807SRob Herring 24b6acf807SRob Herring 25b6acf807SRob Herringdef parse_of_device_id(data): 26b6acf807SRob Herring """ Find all compatible strings in of_device_id structs """ 27b6acf807SRob Herring compat_list = [] 28abe916c5SRob Herring for m in re.finditer(r'of_device_id(\s+\S+)?\s+\S+\[\](\s+\S+)?\s*=\s*({.*?);', data): 29abe916c5SRob Herring compat_list += re.findall(r'\.compatible\s+=\s+"(\S+)"', m[3]) 30b6acf807SRob Herring 31b6acf807SRob Herring return compat_list 32b6acf807SRob Herring 33b6acf807SRob Herring 34b6acf807SRob Herringdef parse_compatibles(file): 35b6acf807SRob Herring with open(file, 'r', encoding='utf-8') as f: 36b6acf807SRob Herring data = f.read().replace('\n', '') 37b6acf807SRob Herring 38b6acf807SRob Herring compat_list = parse_of_declare_macros(data) 39b6acf807SRob Herring compat_list += parse_of_device_id(data) 40b6acf807SRob Herring 41b6acf807SRob Herring return compat_list 42b6acf807SRob Herring 43b6acf807SRob Herringdef print_compat(filename, compatibles): 44b6acf807SRob Herring if not compatibles: 45b6acf807SRob Herring return 46b6acf807SRob Herring if show_filename: 47b6acf807SRob Herring compat_str = ' '.join(compatibles) 48b6acf807SRob Herring print(filename + ": compatible(s): " + compat_str) 49b6acf807SRob Herring else: 50b6acf807SRob Herring print(*compatibles, sep='\n') 51b6acf807SRob Herring 52*7cb7001eSNícolas F. R. A. Pradodef glob_without_symlinks(root, glob): 53*7cb7001eSNícolas F. R. A. Prado for path, dirs, files in os.walk(root): 54*7cb7001eSNícolas F. R. A. Prado # Ignore hidden directories 55*7cb7001eSNícolas F. R. A. Prado for d in dirs: 56*7cb7001eSNícolas F. R. A. Prado if fnmatch.fnmatch(d, ".*"): 57*7cb7001eSNícolas F. R. A. Prado dirs.remove(d) 58*7cb7001eSNícolas F. R. A. Prado for f in files: 59*7cb7001eSNícolas F. R. A. Prado if fnmatch.fnmatch(f, glob): 60*7cb7001eSNícolas F. R. A. Prado yield os.path.join(path, f) 61*7cb7001eSNícolas F. R. A. Prado 62c35bcedeSNícolas F. R. A. Pradodef files_to_parse(path_args): 63c35bcedeSNícolas F. R. A. Prado for f in path_args: 64c35bcedeSNícolas F. R. A. Prado if os.path.isdir(f): 65*7cb7001eSNícolas F. R. A. Prado for filename in glob_without_symlinks(f, "*.c"): 66c35bcedeSNícolas F. R. A. Prado yield filename 67c35bcedeSNícolas F. R. A. Prado else: 68c35bcedeSNícolas F. R. A. Prado yield f 69c35bcedeSNícolas F. R. A. Prado 70b6acf807SRob Herringshow_filename = False 71b6acf807SRob Herring 72b6acf807SRob Herringif __name__ == "__main__": 73b6acf807SRob Herring ap = argparse.ArgumentParser() 74b6acf807SRob Herring ap.add_argument("cfile", type=str, nargs='*', help="C source files or directories to parse") 75b6acf807SRob Herring ap.add_argument('-H', '--with-filename', help="Print filename with compatibles", action="store_true") 76b6acf807SRob Herring args = ap.parse_args() 77b6acf807SRob Herring 78b6acf807SRob Herring show_filename = args.with_filename 79b6acf807SRob Herring 80c35bcedeSNícolas F. R. A. Prado for f in files_to_parse(args.cfile): 81b6acf807SRob Herring compat_list = parse_compatibles(f) 82b6acf807SRob Herring print_compat(f, compat_list) 83