Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  dt-extract-compatibles   Sprache: unbekannt

 
Spracherkennung für: vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

#!/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)

[ Dauer der Verarbeitung: 0.34 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge