diff options
Diffstat (limited to 'scripts/diffconfig')
-rwxr-xr-x | scripts/diffconfig | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/scripts/diffconfig b/scripts/diffconfig new file mode 100755 index 000000000..43f0f3d27 --- /dev/null +++ b/scripts/diffconfig @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# diffconfig - a tool to compare .config files. +# +# originally written in 2006 by Matt Mackall +# (at least, this was in his bloatwatch source code) +# last worked on 2008 by Tim Bird +# + +import sys, os + +def usage(): + print("""Usage: diffconfig [-h] [-m] [<config1> <config2>] + +Diffconfig is a simple utility for comparing two .config files. +Using standard diff to compare .config files often includes extraneous and +distracting information. This utility produces sorted output with only the +changes in configuration values between the two files. + +Added and removed items are shown with a leading plus or minus, respectively. +Changed items show the old and new values on a single line. + +If -m is specified, then output will be in "merge" style, which has the +changed and new values in kernel config option format. + +If no config files are specified, .config and .config.old are used. + +Example usage: + $ diffconfig .config config-with-some-changes +-EXT2_FS_XATTR n + CRAMFS n -> y + EXT2_FS y -> n + LOG_BUF_SHIFT 14 -> 16 + PRINTK_TIME n -> y +""") + sys.exit(0) + +# returns a dictionary of name/value pairs for config items in the file +def readconfig(config_file): + d = {} + for line in config_file: + line = line[:-1] + if line[:7] == "CONFIG_": + name, val = line[7:].split("=", 1) + d[name] = val + if line[-11:] == " is not set": + d[line[9:-11]] = "n" + return d + +def print_config(op, config, value, new_value): + global merge_style + + if merge_style: + if new_value: + if new_value=="n": + print("# CONFIG_%s is not set" % config) + else: + print("CONFIG_%s=%s" % (config, new_value)) + else: + if op=="-": + print("-%s %s" % (config, value)) + elif op=="+": + print("+%s %s" % (config, new_value)) + else: + print(" %s %s -> %s" % (config, value, new_value)) + +def show_diff(): + global merge_style + + # parse command line args + if ("-h" in sys.argv or "--help" in sys.argv): + usage() + + merge_style = 0 + if "-m" in sys.argv: + merge_style = 1 + sys.argv.remove("-m") + + argc = len(sys.argv) + if not (argc==1 or argc == 3): + print("Error: incorrect number of arguments or unrecognized option") + usage() + + if argc == 1: + # if no filenames given, assume .config and .config.old + build_dir="" + if "KBUILD_OUTPUT" in os.environ: + build_dir = os.environ["KBUILD_OUTPUT"]+"/" + configa_filename = build_dir + ".config.old" + configb_filename = build_dir + ".config" + else: + configa_filename = sys.argv[1] + configb_filename = sys.argv[2] + + try: + a = readconfig(open(configa_filename)) + b = readconfig(open(configb_filename)) + except (IOError): + e = sys.exc_info()[1] + print("I/O error[%s]: %s\n" % (e.args[0],e.args[1])) + usage() + + # print items in a but not b (accumulate, sort and print) + old = [] + for config in a: + if config not in b: + old.append(config) + old.sort() + for config in old: + print_config("-", config, a[config], None) + del a[config] + + # print items that changed (accumulate, sort, and print) + changed = [] + for config in a: + if a[config] != b[config]: + changed.append(config) + else: + del b[config] + changed.sort() + for config in changed: + print_config("->", config, a[config], b[config]) + del b[config] + + # now print items in b but not in a + # (items from b that were in a were removed above) + new = sorted(b.keys()) + for config in new: + print_config("+", config, None, b[config]) + +def main(): + try: + show_diff() + except BrokenPipeError: + # Python flushes standard streams on exit; redirect remaining output + # to devnull to avoid another BrokenPipeError at shutdown + devnull = os.open(os.devnull, os.O_WRONLY) + os.dup2(devnull, sys.stdout.fileno()) + sys.exit(1) # Python exits with error code 1 on EPIPE + + +if __name__ == '__main__': + main() |