#!/usr/bin/env python3
#
# 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 for the Linux kernel
# Adapted to Buildroot 2017 by Marcus Folkesson
#

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
-BR2_LINUX_KERNEL_INTREE_DTS_NAME "vexpress-v2p-ca9"
 BR2_LINUX_KERNEL_DTS_SUPPORT y -> n
 BR2_LINUX_KERNEL_USE_INTREE_DTS y -> n
 BR2_PACKAGE_DFU_UTIL n -> y
 BR2_PACKAGE_LIBUSB n -> y
 BR2_TARGET_GENERIC_HOSTNAME "buildroot" -> "Tuxie"
 BR2_TARGET_GENERIC_ISSUE "Welcome to Buildroot" -> "Welcome to CustomBoard"
+BR2_PACKAGE_LIBUSB_COMPAT n

""")
    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.strip()
        if len(line) == 0:
            continue
        if line[-11:] == " is not set":
            d[line[2:-11]] = "n"
        elif line[0] != "#":
            name, val = line.split("=", 1)
            d[name] = val
    return d

def print_config(op, config, value, new_value):
    global merge_style

    if merge_style:
        if new_value:
            if new_value=="n":
                print("# %s is not set" % config)
            else:
                print("%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 main():
    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])

main()
