#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only

import fnmatch
import os
import re
import argparse


def parse_of_declare_macros(data, include_driver_macros=True):
	""" Find all compatible strings in OF_DECLARE() style macros """
	compat_list = []
	# CPU_METHOD_OF_DECLARE does not have a compatible string
	if include_driver_macros:
		re_macros = r'(?<!CPU_METHOD_)(IRQCHIP|OF)_(DECLARE|MATCH)(_DRIVER)?\(.*?\)'
	else:
		re_macros = r'(?<!CPU_METHOD_)(IRQCHIP|OF)_(DECLARE|MATCH)\(.*?\)'
	for m in re.finditer(re_macros, data):
		try:
			compat = re.search(r'"(.*?)"', m[0])[1]
		except:
			# Fails on compatible strings in #define, so just skip
			continue
		compat_list += [compat]

	return compat_list


def parse_of_device_id(data, match_table_list=None):
	""" Find all compatible strings in of_device_id structs """
	compat_list = []
	for m in re.finditer(r'of_device_id(\s+\S+)?\s+(\S+)\[\](\s+\S+)?\s*=\s*({.*?);', data):
		if match_table_list is not None and m[2] not in match_table_list:
			continue
		compat_list += re.findall(r'\.compatible\s+=\s+"(\S+)"', m[4])

	return compat_list


def parse_of_match_table(data):
	""" Find all driver's of_match_table """
	match_table_list = []
	for m in re.finditer(r'\.of_match_table\s+=\s+(of_match_ptr\()?([a-zA-Z0-9_-]+)', data):
		match_table_list.append(m[2])

	return match_table_list


def parse_of_functions(data, func_name):
	""" Find all compatibles in the last argument of a given function """
	compat_list = []
	for m in re.finditer(rf'{func_name}\(([a-zA-Z0-9_>\(\)"\-]+,\s)*"([a-zA-Z0-9_,-]+)"\)', data):
		compat_list.append(m[2])

	return compat_list


def parse_compatibles(file, compat_ignore_list):
	with open(file, 'r', encoding='utf-8') as f:
		data = f.read().replace('\n', '')

	if compat_ignore_list is not None:
		# For a compatible in the DT to be matched to a driver it needs to show
		# up in a driver's of_match_table
		match_table_list = parse_of_match_table(data)
		compat_list = parse_of_device_id(data, match_table_list)

		compat_list = [compat for compat in compat_list if compat not in compat_ignore_list]
	else:
		compat_list = parse_of_declare_macros(data)
		compat_list += parse_of_device_id(data)
		compat_list += parse_of_functions(data, "_is_compatible")
		compat_list += parse_of_functions(data, "of_find_compatible_node")
		compat_list += parse_of_functions(data, "for_each_compatible_node")
		compat_list += parse_of_functions(data, "of_get_compatible_child")

	return compat_list

def parse_compatibles_to_ignore(file):
	with open(file, 'r', encoding='utf-8') as f:
		data = f.read().replace('\n', '')

	# Compatibles that show up in OF_DECLARE macros can't be expected to
	# match a driver, except for the _DRIVER ones.
	return parse_of_declare_macros(data, include_driver_macros=False)


def print_compat(filename, compatibles):
	if not compatibles:
		return
	if show_filename:
		compat_str = ' '.join(compatibles)
		print(filename + ": compatible(s): " + compat_str)
	else:
		print(*compatibles, sep='\n')

def glob_without_symlinks(root, glob):
	for path, dirs, files in os.walk(root):
		# Ignore hidden directories
		for d in dirs:
			if fnmatch.fnmatch(d, ".*"):
				dirs.remove(d)
		for f in files:
			if fnmatch.fnmatch(f, glob):
				yield os.path.join(path, f)

def files_to_parse(path_args):
	for f in path_args:
		if os.path.isdir(f):
			for filename in glob_without_symlinks(f, "*.c"):
				yield filename
		else:
			yield f

show_filename = False

if __name__ == "__main__":
	ap = argparse.ArgumentParser()
	ap.add_argument("cfile", type=str, nargs='*', help="C source files or directories to parse")
	ap.add_argument('-H', '--with-filename', help="Print filename with compatibles", action="store_true")
	ap.add_argument('-d', '--driver-match', help="Only print compatibles that should match to a driver", action="store_true")
	args = ap.parse_args()

	show_filename = args.with_filename
	compat_ignore_list = None

	if args.driver_match:
		compat_ignore_list = []
		for f in files_to_parse(args.cfile):
			compat_ignore_list.extend(parse_compatibles_to_ignore(f))

	for f in files_to_parse(args.cfile):
		compat_list = parse_compatibles(f, compat_ignore_list)
		print_compat(f, compat_list)
