blob: 0db267d0adc9231de508b4cf9ca7068df8362384 [file] [log] [blame]
Tim Birda7174172008-06-24 10:56:06 -07001#!/usr/bin/python
2#
3# diffconfig - a tool to compare .config files.
4#
5# originally written in 2006 by Matt Mackall
6# (at least, this was in his bloatwatch source code)
7# last worked on 2008 by Tim Bird
8#
9
10import sys, os
11
12def usage():
Mike Paganoc8272fa2013-08-20 14:41:12 -040013 print("""Usage: diffconfig [-h] [-m] [<config1> <config2>]
Tim Birda7174172008-06-24 10:56:06 -070014
15Diffconfig is a simple utility for comparing two .config files.
16Using standard diff to compare .config files often includes extraneous and
17distracting information. This utility produces sorted output with only the
18changes in configuration values between the two files.
19
20Added and removed items are shown with a leading plus or minus, respectively.
21Changed items show the old and new values on a single line.
22
23If -m is specified, then output will be in "merge" style, which has the
24changed and new values in kernel config option format.
25
26If no config files are specified, .config and .config.old are used.
27
28Example usage:
29 $ diffconfig .config config-with-some-changes
30-EXT2_FS_XATTR n
Tim Birda7174172008-06-24 10:56:06 -070031 CRAMFS n -> y
32 EXT2_FS y -> n
33 LOG_BUF_SHIFT 14 -> 16
34 PRINTK_TIME n -> y
Mike Paganoc8272fa2013-08-20 14:41:12 -040035""")
Tim Birda7174172008-06-24 10:56:06 -070036 sys.exit(0)
37
38# returns a dictionary of name/value pairs for config items in the file
39def readconfig(config_file):
40 d = {}
41 for line in config_file:
42 line = line[:-1]
43 if line[:7] == "CONFIG_":
44 name, val = line[7:].split("=", 1)
45 d[name] = val
46 if line[-11:] == " is not set":
47 d[line[9:-11]] = "n"
48 return d
49
50def print_config(op, config, value, new_value):
51 global merge_style
52
53 if merge_style:
54 if new_value:
55 if new_value=="n":
Mike Paganoc8272fa2013-08-20 14:41:12 -040056 print("# CONFIG_%s is not set" % config)
Tim Birda7174172008-06-24 10:56:06 -070057 else:
Mike Paganoc8272fa2013-08-20 14:41:12 -040058 print("CONFIG_%s=%s" % (config, new_value))
Tim Birda7174172008-06-24 10:56:06 -070059 else:
60 if op=="-":
Mike Paganoc8272fa2013-08-20 14:41:12 -040061 print("-%s %s" % (config, value))
Tim Birda7174172008-06-24 10:56:06 -070062 elif op=="+":
Mike Paganoc8272fa2013-08-20 14:41:12 -040063 print("+%s %s" % (config, new_value))
Tim Birda7174172008-06-24 10:56:06 -070064 else:
Mike Paganoc8272fa2013-08-20 14:41:12 -040065 print(" %s %s -> %s" % (config, value, new_value))
Tim Birda7174172008-06-24 10:56:06 -070066
67def main():
68 global merge_style
69
70 # parse command line args
71 if ("-h" in sys.argv or "--help" in sys.argv):
Mike Paganoc8272fa2013-08-20 14:41:12 -040072 usage()
Tim Birda7174172008-06-24 10:56:06 -070073
74 merge_style = 0
75 if "-m" in sys.argv:
76 merge_style = 1
77 sys.argv.remove("-m")
78
79 argc = len(sys.argv)
80 if not (argc==1 or argc == 3):
Mike Paganoc8272fa2013-08-20 14:41:12 -040081 print("Error: incorrect number of arguments or unrecognized option")
Tim Birda7174172008-06-24 10:56:06 -070082 usage()
83
84 if argc == 1:
85 # if no filenames given, assume .config and .config.old
86 build_dir=""
Mike Paganoc8272fa2013-08-20 14:41:12 -040087 if "KBUILD_OUTPUT" in os.environ:
Tim Birda7174172008-06-24 10:56:06 -070088 build_dir = os.environ["KBUILD_OUTPUT"]+"/"
Tim Birda7174172008-06-24 10:56:06 -070089 configa_filename = build_dir + ".config.old"
90 configb_filename = build_dir + ".config"
91 else:
92 configa_filename = sys.argv[1]
93 configb_filename = sys.argv[2]
94
Mike Pagano6bf2e842013-08-16 14:40:56 -040095 try:
Mike Paganoc8272fa2013-08-20 14:41:12 -040096 a = readconfig(open(configa_filename))
97 b = readconfig(open(configb_filename))
Mike Pagano6bf2e842013-08-16 14:40:56 -040098 except (IOError):
99 e = sys.exc_info()[1]
100 print("I/O error[%s]: %s\n" % (e.args[0],e.args[1]))
101 usage()
Tim Birda7174172008-06-24 10:56:06 -0700102
103 # print items in a but not b (accumulate, sort and print)
104 old = []
105 for config in a:
106 if config not in b:
107 old.append(config)
108 old.sort()
109 for config in old:
110 print_config("-", config, a[config], None)
111 del a[config]
112
113 # print items that changed (accumulate, sort, and print)
114 changed = []
115 for config in a:
116 if a[config] != b[config]:
117 changed.append(config)
118 else:
119 del b[config]
120 changed.sort()
121 for config in changed:
122 print_config("->", config, a[config], b[config])
123 del b[config]
124
125 # now print items in b but not in a
126 # (items from b that were in a were removed above)
Mike Paganoc8272fa2013-08-20 14:41:12 -0400127 new = sorted(b.keys())
Tim Birda7174172008-06-24 10:56:06 -0700128 for config in new:
129 print_config("+", config, None, b[config])
130
131main()