123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #! /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()
|