aboutsummaryrefslogtreecommitdiffstats
path: root/tools/make-regs.py
blob: 7cb8a2285c935af492c124d6a04868cc65cf68f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python
#
# Looks for registration routines in the source files
# and assembles C code to call all the routines.
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

import sys
import re

preamble = """\
/*
 * Do not modify this file. Changes will be overwritten.
 *
 * Generated automatically using \"make-regs.py\".
 */

"""

def gen_prototypes(funcs):
    output = ""
    for f in funcs:
        output += "void {}(void);\n".format(f)
    return output

def gen_array(funcs, name):
    output = "{}[] = {{\n".format(name)
    for f in funcs:
        output += "    {{ \"{0}\", {0} }},\n".format(f)
    output += "    { NULL, NULL }\n};\n"
    return output

def scan_files(infiles, regs):
    for path in infiles:
        with open(path, 'r') as f:
            source = f.read()
            for array, regex in regs:
                matches = re.findall(regex, source)
                array.extend(matches)

def make_dissectors(outfile, infiles):
    protos = []
    protos_regex = r"void\s+(proto_register_[\w]+)\s*\(\s*void\s*\)\s*{"
    handoffs = []
    handoffs_regex = r"void\s+(proto_reg_handoff_[\w]+)\s*\(\s*void\s*\)\s*{"

    scan_files(infiles, [(protos, protos_regex), (handoffs, handoffs_regex)])

    if len(protos) < 1:
        sys.exit("No protocol registrations found.")

    protos.sort()
    handoffs.sort()

    output = preamble
    output += """\
#include "dissectors.h"

const gulong dissector_reg_proto_count = {0};
const gulong dissector_reg_handoff_count = {1};

""".format(len(protos), len(handoffs))

    output += gen_prototypes(protos)
    output += "\n"
    output += gen_array(protos, "dissector_reg_t dissector_reg_proto")
    output += "\n"
    output += gen_prototypes(handoffs)
    output += "\n"
    output += gen_array(handoffs, "dissector_reg_t dissector_reg_handoff")

    with open(outfile, "w") as f:
        f.write(output)

    print("Found {0} registrations and {1} handoffs.".format(len(protos), len(handoffs)))

def make_taps(outfile, infiles):
    taps = []
    taps_regex = r"void\s+(register_tap_listener_[\w]+)\s*\(\s*void\s*\)\s*{"

    scan_files(infiles, [(taps, taps_regex)])

    if len(taps) < 1:
        sys.exit("No tap registrations found.")

    taps.sort()

    output = preamble
    output += """\
#include "ui/taps.h"

const gulong tap_reg_listener_count = {0};

""".format(len(taps))

    output += gen_prototypes(taps)
    output += "\n"
    output += gen_array(taps, "tap_reg_t tap_reg_listener")

    with open(outfile, "w") as f:
        f.write(output)

    print("Found {0} registrations.".format(len(taps)))


def print_usage():
    sys.exit("Usage: {0} <dissectors|taps> <outfile> <infiles...|@filelist>\n".format(sys.argv[0]))

if __name__ == "__main__":
    if len(sys.argv) < 4:
        print_usage()

    mode = sys.argv[1]
    outfile = sys.argv[2]
    if sys.argv[3].startswith("@"):
        with open(sys.argv[3][1:]) as f:
            infiles = [l.strip() for l in f.readlines()]
    else:
        infiles = sys.argv[3:]

    if mode == "dissectors":
        make_dissectors(outfile, infiles)
    elif mode == "taps":
        make_taps(outfile, infiles)
    else:
        print_usage()