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