linux/tools/testing/kunit/kunit_config.py
<<
>>
Prefs
   1# SPDX-License-Identifier: GPL-2.0
   2#
   3# Builds a .config from a kunitconfig.
   4#
   5# Copyright (C) 2019, Google LLC.
   6# Author: Felix Guo <felixguoxiuping@gmail.com>
   7# Author: Brendan Higgins <brendanhiggins@google.com>
   8
   9import collections
  10import re
  11
  12CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$'
  13CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
  14
  15KconfigEntryBase = collections.namedtuple('KconfigEntry', ['name', 'value'])
  16
  17class KconfigEntry(KconfigEntryBase):
  18
  19        def __str__(self) -> str:
  20                if self.value == 'n':
  21                        return r'# CONFIG_%s is not set' % (self.name)
  22                else:
  23                        return r'CONFIG_%s=%s' % (self.name, self.value)
  24
  25
  26class KconfigParseError(Exception):
  27        """Error parsing Kconfig defconfig or .config."""
  28
  29
  30class Kconfig(object):
  31        """Represents defconfig or .config specified using the Kconfig language."""
  32
  33        def __init__(self):
  34                self._entries = []
  35
  36        def entries(self):
  37                return set(self._entries)
  38
  39        def add_entry(self, entry: KconfigEntry) -> None:
  40                self._entries.append(entry)
  41
  42        def is_subset_of(self, other: 'Kconfig') -> bool:
  43                for a in self.entries():
  44                        found = False
  45                        for b in other.entries():
  46                                if a.name != b.name:
  47                                        continue
  48                                if a.value != b.value:
  49                                        return False
  50                                found = True
  51                        if a.value != 'n' and found == False:
  52                                return False
  53                return True
  54
  55        def write_to_file(self, path: str) -> None:
  56                with open(path, 'w') as f:
  57                        for entry in self.entries():
  58                                f.write(str(entry) + '\n')
  59
  60        def parse_from_string(self, blob: str) -> None:
  61                """Parses a string containing KconfigEntrys and populates this Kconfig."""
  62                self._entries = []
  63                is_not_set_matcher = re.compile(CONFIG_IS_NOT_SET_PATTERN)
  64                config_matcher = re.compile(CONFIG_PATTERN)
  65                for line in blob.split('\n'):
  66                        line = line.strip()
  67                        if not line:
  68                                continue
  69
  70                        match = config_matcher.match(line)
  71                        if match:
  72                                entry = KconfigEntry(match.group(1), match.group(2))
  73                                self.add_entry(entry)
  74                                continue
  75
  76                        empty_match = is_not_set_matcher.match(line)
  77                        if empty_match:
  78                                entry = KconfigEntry(empty_match.group(1), 'n')
  79                                self.add_entry(entry)
  80                                continue
  81
  82                        if line[0] == '#':
  83                                continue
  84                        else:
  85                                raise KconfigParseError('Failed to parse: ' + line)
  86
  87        def read_from_file(self, path: str) -> None:
  88                with open(path, 'r') as f:
  89                        self.parse_from_string(f.read())
  90