Files
ethercat/devices/create_driver_table.py
2024-04-03 10:33:12 +02:00

165 lines
5.0 KiB
Python

#!/usr/bin/env python3
#############################################################################
#
# Copyright (C) 2007-2023 Bjarne von Horn, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT Master.
#
# The IgH EtherCAT Master is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2, as
# published by the Free Software Foundation.
#
# The IgH EtherCAT Master is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with the IgH EtherCAT Master; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
############################################################################
from os import walk
from os.path import join
from re import compile
DRIVER_MAP=(
# (subdir, driver name, file prefix)
(".", "8139too", "8139too"),
("stmmac", "dwmac-intel", "dwmac-intel"),
(".", "e100", "e100"),
("e1000", "e1000", "e1000_main"),
("e1000e", "e1000e", "netdev"),
("genet", "bcmgenet", "bcmgenet"),
("igb", "igb", "igb_main"),
("igc", "igc", "igc_main"),
(".", "r8169", "r8169"),
("r8169", "r8169", "r8169_main"),
("stmmac", "stmmac-pci", "stmmac_pci"),
)
DRIVERS = sorted(set([x[1] for x in DRIVER_MAP]))
def compile_regex(prefix, file_extension):
"""
:return: Compiled regex to extract Kernel version
"""
return compile("^" + prefix + "-([\d]+)\.([\d]+)-ethercat\."+file_extension+"$")
def filter_versions(file_list, prefix, file_extension):
"""
:return: Set of tuples with (major, minor) kernel versions.
"""
rex = compile_regex(prefix, file_extension)
ans = set()
for file in file_list:
match = rex.match(file)
if match is None:
continue
maj, min = match.group(1, 2)
ans.add((int(maj), int(min)))
return ans
def get_all_drivers(drivers_dir):
"""
Walk through "devices" dir and collect all drivers.
:return: Dict with (major, minor) kernel version key and set of driver
names as values.
"""
files = next(walk(drivers_dir))[2]
driver_table = {}
def add_driver(versions, driver):
for version in versions:
if not version in driver_table:
driver_table[version] = set()
driver_table[version].add(driver)
for subdir, driver_name, file_prefix in DRIVER_MAP:
if subdir == ".":
add_driver(filter_versions(files, file_prefix, "c"), driver_name)
else:
tmp_files = next(walk(join(drivers_dir, subdir)))[2]
add_driver(filter_versions(tmp_files, file_prefix, "c"), driver_name)
return driver_table
def compute_table(dict_data):
"""
Create a table based on data generated by get_all_drivers().
:return: List of rows with "X" or "-", including column and row captions
(driver name / kernel version).
"""
keys = sorted(dict_data.keys(), reverse=True)
ans = [("Kernel", *DRIVERS),]
def parse_row(key):
row_set = dict_data[key]
row = []
for driver in DRIVERS:
if driver in row_set:
row.append("X")
else:
row.append("-")
return row
for key in keys:
c = "{}.{: <2}".format(*key)
ans.append([c] + parse_row(key))
return ans
def get_max_width(row):
ans = 0
for cell in row:
if len(cell) > ans:
ans = len(cell)
return ans
def dump_markdown(table_data):
"""
Create a markdown table based on data from compute_table().
"""
width = get_max_width(table_data[0])
cell_fmt_center = "| {: ^" + str(width) + "} "
cell_fmt_left = "| {: <" + str(width) + "} "
cell_fmt_right = "| {: >" + str(width) + "} "
ans = cell_fmt_left.format(table_data[0][0])
for cell in table_data[0][1:]:
ans += cell_fmt_center.format(cell)
ans += '|\n|-' + "-" * width + ":|"
for i in range(len(table_data[0]) - 1):
ans += ':' + "-" * width + ':|'
for row in table_data[1:]:
ans += '\n' + cell_fmt_right.format(row[0])
for cell in row[1:]:
ans += cell_fmt_center.format(cell)
ans += '|'
return ans
if __name__ == "__main__":
from sys import argv
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"--markdown",
nargs=1,
help="Markdown output file",
type=argparse.FileType("w")
)
parser.add_argument(
"devices_dir",
nargs=1,
help="Devices driver source dir"
)
args = parser.parse_args(argv[1:])
table = compute_table(get_all_drivers(args.devices_dir[0]))
if args.markdown is not None:
with args.markdown[0] as f:
f.write(dump_markdown(table))
f.write('\n')