blob: eaf87b11a8c6c632d7b4e8b63624a09dcf322fce [file] [log] [blame]
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -05001#!/usr/bin/env python3
2
Willy Tu40553242022-11-14 09:27:39 -08003import re
4import sys
5
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -05006
7def usage():
8 sys.stderr.write("Usage: $0 whitelist-config-in whitelist-header-out\n")
9 sys.stderr.write(" Reads in whitelist config, sorting the contents\n")
10 sys.stderr.write(" and outputs a header file\n")
11 sys.exit(-1)
12
Willy Tu40553242022-11-14 09:27:39 -080013
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050014class Error(Exception):
15 pass
16
Willy Tu40553242022-11-14 09:27:39 -080017
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050018class DuplicateEntry(Error):
19 def __init__(self, e):
20 super(Error, self).__init__(
Willy Tu40553242022-11-14 09:27:39 -080021 "Multiple entries with matching netfn/cmd found ({})".format(e)
22 )
23
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050024
25class ParseError(Error):
26 def __init__(self, d):
27 super(Error, self).__init__("Parse error at: '{}'".format(d))
28
Willy Tu40553242022-11-14 09:27:39 -080029
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050030class entry:
31 linere = re.compile(
Willy Tu40553242022-11-14 09:27:39 -080032 r"(0x[0-9a-f]{2}):(0x[0-9a-f]{2})((:(0x[0-9a-f]{4}))?)\s*((//\s*(.*))?)",
33 re.I,
34 )
35
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050036 def __init__(self, data):
37 # parse data line into values:
38 # type 1, two values: netfn, cmd
39 # type 2, three values: netfn, cmd, channels
40 try:
41 m = self.linere.fullmatch(data).groups()
Willy Tu40553242022-11-14 09:27:39 -080042 except Exception:
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050043 raise ParseError(data)
44 self.netfn = int(m[0], 16)
45 self.cmd = int(m[1], 16)
46 if m[4] is not None:
47 self.channels = int(m[4], 16)
48 else:
49 # if no channel was provided, default to previous behavior, which
50 # is allow all interfaces, including the system interface (ch 15)
Willy Tu40553242022-11-14 09:27:39 -080051 self.channels = 0xFFFF
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050052 if m[6] is not None:
53 self.comment = "// " + m[7]
54 else:
55 self.comment = "//"
Willy Tu40553242022-11-14 09:27:39 -080056
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050057 def __str__(self):
Willy Tu40553242022-11-14 09:27:39 -080058 return " ".join(
59 [
60 "{",
61 "0x{0.netfn:02x},".format(self),
62 "0x{0.cmd:02x},".format(self),
63 "0x{0.channels:04x}".format(self),
64 "},",
65 "{0.comment}".format(self),
66 ]
67 )
68
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050069 def __lt__(self, other):
70 if self.netfn == other.netfn:
71 return self.cmd < other.cmd
72 return self.netfn < other.netfn
Willy Tu40553242022-11-14 09:27:39 -080073
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050074 def match(self, other):
75 return (self.netfn == other.netfn) and (self.cmd == other.cmd)
76
Willy Tu40553242022-11-14 09:27:39 -080077
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050078def parse(config):
79 entries = []
80 with open(config) as f:
81 for line in f:
82 line = line.strip()
Willy Tu40553242022-11-14 09:27:39 -080083 if len(line) == 0 or line[0] == "#":
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050084 continue
85 e = entry(line)
86 if any([e.match(item) for item in entries]):
87 d = DuplicateEntry(e)
88 sys.stderr.write("WARNING: {}\n".format(d))
89 else:
90 entries.append(e)
91 entries.sort()
92 return entries
93
Willy Tu40553242022-11-14 09:27:39 -080094
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -050095def output(entries, hppfile):
96 lines = [
Willy Tu40553242022-11-14 09:27:39 -080097 "#pragma once",
98 "",
99 "// AUTOGENERATED FILE; DO NOT MODIFY",
100 "",
101 "#include <array>",
102 "#include <tuple>",
103 "",
104 (
105 "using netfncmd_tuple = std::tuple<unsigned char, unsigned char,"
106 " unsigned short>;"
107 ),
108 "",
109 "constexpr const std::array<netfncmd_tuple, {}> whitelist = ".format(
110 len(entries)
111 ),
112 "{{",
113 ]
114 lines.extend([" {}".format(e) for e in entries])
115 lines.append("}};\n")
Mohaimen Alsamarai35c1ac42021-04-20 13:16:42 -0500116
117 with open(hppfile, "w") as hpp:
118 hpp.write("\n".join(lines))
119
120
121if __name__ == "__main__":
122 if len(sys.argv) != 3:
123 usage()
124 config = sys.argv[1]
125 header = sys.argv[2]
126 entries = parse(config)
127 output(entries, header)