blob: 0db267d0adc9231de508b4cf9ca7068df8362384
1 | #!/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 | |
10 | import sys, os |
11 | |
12 | def usage(): |
13 | print("""Usage: diffconfig [-h] [-m] [<config1> <config2>] |
14 | |
15 | Diffconfig is a simple utility for comparing two .config files. |
16 | Using standard diff to compare .config files often includes extraneous and |
17 | distracting information. This utility produces sorted output with only the |
18 | changes in configuration values between the two files. |
19 | |
20 | Added and removed items are shown with a leading plus or minus, respectively. |
21 | Changed items show the old and new values on a single line. |
22 | |
23 | If -m is specified, then output will be in "merge" style, which has the |
24 | changed and new values in kernel config option format. |
25 | |
26 | If no config files are specified, .config and .config.old are used. |
27 | |
28 | Example usage: |
29 | $ diffconfig .config config-with-some-changes |
30 | -EXT2_FS_XATTR n |
31 | CRAMFS n -> y |
32 | EXT2_FS y -> n |
33 | LOG_BUF_SHIFT 14 -> 16 |
34 | PRINTK_TIME n -> y |
35 | """) |
36 | sys.exit(0) |
37 | |
38 | # returns a dictionary of name/value pairs for config items in the file |
39 | def 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 | |
50 | def 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": |
56 | print("# CONFIG_%s is not set" % config) |
57 | else: |
58 | print("CONFIG_%s=%s" % (config, new_value)) |
59 | else: |
60 | if op=="-": |
61 | print("-%s %s" % (config, value)) |
62 | elif op=="+": |
63 | print("+%s %s" % (config, new_value)) |
64 | else: |
65 | print(" %s %s -> %s" % (config, value, new_value)) |
66 | |
67 | def main(): |
68 | global merge_style |
69 | |
70 | # parse command line args |
71 | if ("-h" in sys.argv or "--help" in sys.argv): |
72 | usage() |
73 | |
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): |
81 | print("Error: incorrect number of arguments or unrecognized option") |
82 | usage() |
83 | |
84 | if argc == 1: |
85 | # if no filenames given, assume .config and .config.old |
86 | build_dir="" |
87 | if "KBUILD_OUTPUT" in os.environ: |
88 | build_dir = os.environ["KBUILD_OUTPUT"]+"/" |
89 | 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 | |
95 | try: |
96 | a = readconfig(open(configa_filename)) |
97 | b = readconfig(open(configb_filename)) |
98 | except (IOError): |
99 | e = sys.exc_info()[1] |
100 | print("I/O error[%s]: %s\n" % (e.args[0],e.args[1])) |
101 | usage() |
102 | |
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) |
127 | new = sorted(b.keys()) |
128 | for config in new: |
129 | print_config("+", config, None, b[config]) |
130 | |
131 | main() |
132 |