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