From 8631fcb308c1627bb9277e00de6225b080cdb501 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 9 Aug 2023 19:31:39 +0200 Subject: [PATCH] initial script to create device table --- devices/Makefile.am | 1 + devices/create_driver_table.py | 137 +++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 devices/create_driver_table.py diff --git a/devices/Makefile.am b/devices/Makefile.am index cc522114..4b3931a8 100644 --- a/devices/Makefile.am +++ b/devices/Makefile.am @@ -95,6 +95,7 @@ noinst_HEADERS = \ 8139too-4.4-orig.c \ 8139too-5.10-ethercat.c \ 8139too-5.10-orig.c \ + create_driver_table.py \ e100-2.6.20-ethercat.c \ e100-2.6.20-orig.c \ e100-2.6.24-ethercat.c \ diff --git a/devices/create_driver_table.py b/devices/create_driver_table.py new file mode 100644 index 00000000..a95ff1ba --- /dev/null +++ b/devices/create_driver_table.py @@ -0,0 +1,137 @@ +#!/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 +# +# --- +# +# The license mentioned above concerns the source code only. Using the +# EtherCAT technology and brand is only permitted in compliance with the +# industrial property and similar rights of Beckhoff Automation GmbH. +# +############################################################################ + +from os import walk +from os.path import join +from re import compile + +DRIVER_MAP=( + # (subdir, driver name, file prefix) + (".", "8139too", "8139too"), + (".", "e100", "e100"), + ("e1000", "e1000", "e1000_main"), + ("e1000e", "e1000e", "netdev"), + ("igb", "igb", "igb_main"), + (".", "r8169", "r8169"), +) + +DRIVERS = tuple([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) + 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