1#!/usr/bin/env python
2
3# The format of the kernel configs in the framework compatibility matrix
4# has a couple properties that would make it confusing or cumbersome to
5# maintain by hand:
6#
7#  - Conditions apply to all configs within the same <kernel> section.
8#    The <kernel> tag also specifies the LTS version. Since the entire
9#    file in the kernel/configs repo is for a single kernel version,
10#    the section is renamed as a "group", and the LTS version is
11#    specified once at the top of the file with a tag of the form
12#    <kernel minlts="x.y.z" />.
13#  - The compatibility matrix understands all kernel config options as
14#    tristate values. In reality however some kernel config options are
15#    boolean. This script simply converts booleans to tristates so we
16#    can avoid describing boolean values as tristates in hand-maintained
17#    files.
18#
19
20from __future__ import print_function
21import argparse
22import os
23import re
24import sys
25
26def fixup(args):
27    source_f = open(args.input) or die ("Could not open %s" % args.input)
28
29    # The first line of the conditional xml has the tag containing
30    # the kernel min LTS version.
31    line = source_f.readline()
32    exp_re = re.compile(r"^<kernel minlts=\"(\d+).(\d+).(\d+)\"\s+/>")
33    exp_match = re.match(exp_re, line)
34    assert exp_match, "Malformatted kernel conditional config file.\n"
35
36    major = exp_match.group(1)
37    minor = exp_match.group(2)
38    tiny = exp_match.group(3)
39
40    if args.output_version:
41        version_f = (open(args.output_version, "w+") or
42                  die("Could not open version file"))
43        version_f.write("{}.{}.{}".format(major, minor, tiny))
44        version_f.close()
45
46    if args.output_matrix:
47        dest_f = (open(args.output_matrix, "w+") or
48                  die("Could not open destination file"))
49        dest_f.write("<compatibility-matrix version=\"1.0\" type=\"framework\">\n")
50
51        # First <kernel> must not have <condition> for libvintf backwards compatibility.
52        dest_f.write("<kernel version=\"{}.{}.{}\" />".format(major, minor, tiny))
53
54        line = source_f.readline()
55        while line:
56            line = line.replace("<value type=\"bool\">",
57                    "<value type=\"tristate\">")
58            line = line.replace("<group>",
59                    "<kernel version=\"{}.{}.{}\">".format(major, minor, tiny))
60            line = line.replace("</group>", "</kernel>")
61            dest_f.write(line)
62            line = source_f.readline()
63
64        dest_f.write("</compatibility-matrix>")
65        dest_f.close()
66
67    source_f.close()
68
69if __name__ == '__main__':
70    parser = argparse.ArgumentParser(description=__doc__)
71    parser.add_argument('--input', help='Input file', required=True)
72    parser.add_argument('--output-matrix', help='Output compatibility matrix file')
73    parser.add_argument('--output-version', help='Output version file')
74
75    args = parser.parse_args()
76
77    fixup(args)
78
79    sys.exit(0)
80