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