scripts: snapshot of kernel build utility scripts

This is a snapshot of build scripts taken as of msm-4.4 commit
<400520a6e2f06cc> ("ASoC: msm: qdsp6v2: Fix FE id check in routing
driver").

CRs-Fixed: 1040265
Change-Id: If5774f946d41f2c15503a6641938412c5d3aefb3
Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
diff --git a/scripts/check-config.py b/scripts/check-config.py
new file mode 100755
index 0000000..79c2bdf
--- /dev/null
+++ b/scripts/check-config.py
@@ -0,0 +1,147 @@
+#! /usr/bin/env python
+
+# Copyright (c) 2015, The Linux Foundation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of The Linux Foundation nor
+#       the names of its contributors may be used to endorse or promote
+#       products derived from this software without specific prior written
+#       permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+Android kernel configuration validator.
+
+The Android kernel reference trees contain some config stubs of
+configuration options that are required for Android to function
+correctly, and additional ones that are recommended.
+
+This script can help compare these base configs with the ".config"
+output of the compiler to determine if the proper configs are defined.
+"""
+
+from collections import namedtuple
+from optparse import OptionParser
+import re
+import sys
+
+version = "check-config.py, version 0.0.1"
+
+req_re = re.compile(r'''^CONFIG_(.*)=(.*)$''')
+forb_re = re.compile(r'''^# CONFIG_(.*) is not set$''')
+comment_re = re.compile(r'''^(#.*|)$''')
+
+Enabled = namedtuple('Enabled', ['name', 'value'])
+Disabled = namedtuple('Disabled', ['name'])
+
+def walk_config(name):
+    with open(name, 'r') as fd:
+        for line in fd:
+            line = line.rstrip()
+            m = req_re.match(line)
+            if m:
+                yield Enabled(m.group(1), m.group(2))
+                continue
+
+            m = forb_re.match(line)
+            if m:
+                yield Disabled(m.group(1))
+                continue
+
+            m = comment_re.match(line)
+            if m:
+                continue
+
+            print "WARNING: Unknown .config line: ", line
+
+class Checker():
+    def __init__(self):
+        self.required = {}
+        self.exempted = set()
+        self.forbidden = set()
+
+    def add_required(self, fname):
+        for ent in walk_config(fname):
+            if type(ent) is Enabled:
+                self.required[ent.name] = ent.value
+            elif type(ent) is Disabled:
+                if ent.name in self.required:
+                    del self.required[ent.name]
+                self.forbidden.add(ent.name)
+
+    def add_exempted(self, fname):
+        with open(fname, 'r') as fd:
+            for line in fd:
+                line = line.rstrip()
+                self.exempted.add(line)
+
+    def check(self, path):
+        failure = False
+
+        # Don't run this for mdm targets
+        if re.search('mdm', path):
+            print "Not applicable to mdm targets... bypassing"
+        else:
+            for ent in walk_config(path):
+                # Go to the next iteration if this config is exempt
+                if ent.name in self.exempted:
+                   continue
+
+                if type(ent) is Enabled:
+                    if ent.name in self.forbidden:
+                        print "error: Config should not be present: %s" %ent.name
+                        failure = True
+
+                    if ent.name in self.required and ent.value != self.required[ent.name]:
+                        print "error: Config has wrong value: %s %s expecting: %s" \
+                                 %(ent.name, ent.value, self.required[ent.name])
+                        failure = True
+
+                elif type(ent) is Disabled:
+                    if ent.name in self.required:
+                        print "error: Config should be present, but is disabled: %s" %ent.name
+                        failure = True
+
+        if failure:
+            sys.exit(1)
+
+def main():
+    usage = """%prog [options] path/to/.config"""
+    parser = OptionParser(usage=usage, version=version)
+    parser.add_option('-r', '--required', dest="required",
+            action="append")
+    parser.add_option('-e', '--exempted', dest="exempted",
+            action="append")
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.error("Expecting a single path argument to .config")
+    elif options.required is None or options.exempted is None:
+        parser.error("Expecting a file containing required configurations")
+
+    ch = Checker()
+    for r in options.required:
+        ch.add_required(r)
+    for e in options.exempted:
+        ch.add_exempted(e)
+
+    ch.check(args[0])
+
+if __name__ == '__main__':
+    main()