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