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