]> rtime.felk.cvut.cz Git - coffee/buildroot.git/blob - utils/diffconfig
libftdi: rename option to have proper prefix
[coffee/buildroot.git] / utils / diffconfig
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 for the Linux kernel
8 # Adapted to Buildroot 2017 by Marcus Folkesson
9 #
10
11 import sys, os
12
13 def usage():
14     print("""Usage: diffconfig [-h] [-m] [<config1> <config2>]
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 -LINUX_KERNEL_INTREE_DTS_NAME "vexpress-v2p-ca9"
32  LINUX_KERNEL_DTS_SUPPORT y -> n
33  LINUX_KERNEL_USE_INTREE_DTS y -> n
34  PACKAGE_DFU_UTIL n -> y
35  PACKAGE_LIBUSB n -> y
36  TARGET_GENERIC_HOSTNAME "buildroot" -> "Tuxie"
37  TARGET_GENERIC_ISSUE "Welcome to Buildroot" -> "Welcome to CustomBoard"
38 +PACKAGE_LIBUSB_COMPAT n
39
40 """)
41     sys.exit(0)
42
43 # returns a dictionary of name/value pairs for config items in the file
44 def readconfig(config_file):
45     d = {}
46     for line in config_file:
47         line = line[:-1]
48         if line[:4] == "BR2_":
49             name, val = line[4:].split("=", 1)
50             d[name] = val
51         if line[-11:] == " is not set":
52             d[line[6:-11]] = "n"
53     return d
54
55 def print_config(op, config, value, new_value):
56     global merge_style
57
58     if merge_style:
59         if new_value:
60             if new_value=="n":
61                 print("# BR2_%s is not set" % config)
62             else:
63                 print("BR2_%s=%s" % (config, new_value))
64     else:
65         if op=="-":
66             print("-%s %s" % (config, value))
67         elif op=="+":
68             print("+%s %s" % (config, new_value))
69         else:
70             print(" %s %s -> %s" % (config, value, new_value))
71
72 def main():
73     global merge_style
74
75     # parse command line args
76     if ("-h" in sys.argv or "--help" in sys.argv):
77         usage()
78
79     merge_style = 0
80     if "-m" in sys.argv:
81         merge_style = 1
82         sys.argv.remove("-m")
83
84     argc = len(sys.argv)
85     if not (argc==1 or argc == 3):
86         print("Error: incorrect number of arguments or unrecognized option")
87         usage()
88
89     if argc == 1:
90         # if no filenames given, assume .config and .config.old
91         build_dir=""
92         if "KBUILD_OUTPUT" in os.environ:
93             build_dir = os.environ["KBUILD_OUTPUT"]+"/"
94         configa_filename = build_dir + ".config.old"
95         configb_filename = build_dir + ".config"
96     else:
97         configa_filename = sys.argv[1]
98         configb_filename = sys.argv[2]
99
100     try:
101         a = readconfig(open(configa_filename))
102         b = readconfig(open(configb_filename))
103     except (IOError):
104         e = sys.exc_info()[1]
105         print("I/O error[%s]: %s\n" % (e.args[0],e.args[1]))
106         usage()
107
108     # print items in a but not b (accumulate, sort and print)
109     old = []
110     for config in a:
111         if config not in b:
112             old.append(config)
113     old.sort()
114     for config in old:
115         print_config("-", config, a[config], None)
116         del a[config]
117
118     # print items that changed (accumulate, sort, and print)
119     changed = []
120     for config in a:
121         if a[config] != b[config]:
122             changed.append(config)
123         else:
124             del b[config]
125     changed.sort()
126     for config in changed:
127         print_config("->", config, a[config], b[config])
128         del b[config]
129
130     # now print items in b but not in a
131     # (items from b that were in a were removed above)
132     new = sorted(b.keys())
133     for config in new:
134         print_config("+", config, None, b[config])
135
136 main()