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