xref: /nrf52832-nimble/rt-thread/tools/kconfig-frontends/utils/kconfig-diff (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero#!/usr/bin/python
2*10465441SEvalZero#
3*10465441SEvalZero# diffconfig - a tool to compare .config files.
4*10465441SEvalZero#
5*10465441SEvalZero# originally written in 2006 by Matt Mackall
6*10465441SEvalZero#  (at least, this was in his bloatwatch source code)
7*10465441SEvalZero# last worked on 2008 by Tim Bird
8*10465441SEvalZero#
9*10465441SEvalZero
10*10465441SEvalZeroimport sys, os
11*10465441SEvalZero
12*10465441SEvalZerodef usage():
13*10465441SEvalZero    print("""Usage: diffconfig [-h] [-m] [<config1> <config2>]
14*10465441SEvalZero
15*10465441SEvalZeroDiffconfig is a simple utility for comparing two .config files.
16*10465441SEvalZeroUsing standard diff to compare .config files often includes extraneous and
17*10465441SEvalZerodistracting information.  This utility produces sorted output with only the
18*10465441SEvalZerochanges in configuration values between the two files.
19*10465441SEvalZero
20*10465441SEvalZeroAdded and removed items are shown with a leading plus or minus, respectively.
21*10465441SEvalZeroChanged items show the old and new values on a single line.
22*10465441SEvalZero
23*10465441SEvalZeroIf -m is specified, then output will be in "merge" style, which has the
24*10465441SEvalZerochanged and new values in kernel config option format.
25*10465441SEvalZero
26*10465441SEvalZeroIf no config files are specified, .config and .config.old are used.
27*10465441SEvalZero
28*10465441SEvalZeroExample usage:
29*10465441SEvalZero $ diffconfig .config config-with-some-changes
30*10465441SEvalZero-EXT2_FS_XATTR  n
31*10465441SEvalZero CRAMFS  n -> y
32*10465441SEvalZero EXT2_FS  y -> n
33*10465441SEvalZero LOG_BUF_SHIFT  14 -> 16
34*10465441SEvalZero PRINTK_TIME  n -> y
35*10465441SEvalZero""")
36*10465441SEvalZero    sys.exit(0)
37*10465441SEvalZero
38*10465441SEvalZero# returns a dictionary of name/value pairs for config items in the file
39*10465441SEvalZerodef readconfig(config_file):
40*10465441SEvalZero    d = {}
41*10465441SEvalZero    for line in config_file:
42*10465441SEvalZero        line = line[:-1]
43*10465441SEvalZero        if line[:7] == "CONFIG_":
44*10465441SEvalZero            name, val = line[7:].split("=", 1)
45*10465441SEvalZero            d[name] = val
46*10465441SEvalZero        if line[-11:] == " is not set":
47*10465441SEvalZero            d[line[9:-11]] = "n"
48*10465441SEvalZero    return d
49*10465441SEvalZero
50*10465441SEvalZerodef print_config(op, config, value, new_value):
51*10465441SEvalZero    global merge_style
52*10465441SEvalZero
53*10465441SEvalZero    if merge_style:
54*10465441SEvalZero        if new_value:
55*10465441SEvalZero            if new_value=="n":
56*10465441SEvalZero                print("# CONFIG_%s is not set" % config)
57*10465441SEvalZero            else:
58*10465441SEvalZero                print("CONFIG_%s=%s" % (config, new_value))
59*10465441SEvalZero    else:
60*10465441SEvalZero        if op=="-":
61*10465441SEvalZero            print("-%s %s" % (config, value))
62*10465441SEvalZero        elif op=="+":
63*10465441SEvalZero            print("+%s %s" % (config, new_value))
64*10465441SEvalZero        else:
65*10465441SEvalZero            print(" %s %s -> %s" % (config, value, new_value))
66*10465441SEvalZero
67*10465441SEvalZerodef main():
68*10465441SEvalZero    global merge_style
69*10465441SEvalZero
70*10465441SEvalZero    # parse command line args
71*10465441SEvalZero    if ("-h" in sys.argv or "--help" in sys.argv):
72*10465441SEvalZero        usage()
73*10465441SEvalZero
74*10465441SEvalZero    merge_style = 0
75*10465441SEvalZero    if "-m" in sys.argv:
76*10465441SEvalZero        merge_style = 1
77*10465441SEvalZero        sys.argv.remove("-m")
78*10465441SEvalZero
79*10465441SEvalZero    argc = len(sys.argv)
80*10465441SEvalZero    if not (argc==1 or argc == 3):
81*10465441SEvalZero        print("Error: incorrect number of arguments or unrecognized option")
82*10465441SEvalZero        usage()
83*10465441SEvalZero
84*10465441SEvalZero    if argc == 1:
85*10465441SEvalZero        # if no filenames given, assume .config and .config.old
86*10465441SEvalZero        build_dir=""
87*10465441SEvalZero        if "KBUILD_OUTPUT" in os.environ:
88*10465441SEvalZero            build_dir = os.environ["KBUILD_OUTPUT"]+"/"
89*10465441SEvalZero        configa_filename = build_dir + ".config.old"
90*10465441SEvalZero        configb_filename = build_dir + ".config"
91*10465441SEvalZero    else:
92*10465441SEvalZero        configa_filename = sys.argv[1]
93*10465441SEvalZero        configb_filename = sys.argv[2]
94*10465441SEvalZero
95*10465441SEvalZero    try:
96*10465441SEvalZero        a = readconfig(open(configa_filename))
97*10465441SEvalZero        b = readconfig(open(configb_filename))
98*10465441SEvalZero    except (IOError):
99*10465441SEvalZero        e = sys.exc_info()[1]
100*10465441SEvalZero        print("I/O error[%s]: %s\n" % (e.args[0],e.args[1]))
101*10465441SEvalZero        usage()
102*10465441SEvalZero
103*10465441SEvalZero    # print items in a but not b (accumulate, sort and print)
104*10465441SEvalZero    old = []
105*10465441SEvalZero    for config in a:
106*10465441SEvalZero        if config not in b:
107*10465441SEvalZero            old.append(config)
108*10465441SEvalZero    old.sort()
109*10465441SEvalZero    for config in old:
110*10465441SEvalZero        print_config("-", config, a[config], None)
111*10465441SEvalZero        del a[config]
112*10465441SEvalZero
113*10465441SEvalZero    # print items that changed (accumulate, sort, and print)
114*10465441SEvalZero    changed = []
115*10465441SEvalZero    for config in a:
116*10465441SEvalZero        if a[config] != b[config]:
117*10465441SEvalZero            changed.append(config)
118*10465441SEvalZero        else:
119*10465441SEvalZero            del b[config]
120*10465441SEvalZero    changed.sort()
121*10465441SEvalZero    for config in changed:
122*10465441SEvalZero        print_config("->", config, a[config], b[config])
123*10465441SEvalZero        del b[config]
124*10465441SEvalZero
125*10465441SEvalZero    # now print items in b but not in a
126*10465441SEvalZero    # (items from b that were in a were removed above)
127*10465441SEvalZero    new = sorted(b.keys())
128*10465441SEvalZero    for config in new:
129*10465441SEvalZero        print_config("+", config, None, b[config])
130*10465441SEvalZero
131*10465441SEvalZeromain()
132