| 1 |
import os
|
| 2 |
|
| 3 |
from debian_linux.config import ConfigCoreHierarchy
|
| 4 |
|
| 5 |
from kconfigeditor.kconfig.menu.file import FileConfig
|
| 6 |
|
| 7 |
class Files(dict):
|
| 8 |
def __init__(self, root):
|
| 9 |
self.kernelarch = {}
|
| 10 |
self.files = {}
|
| 11 |
self.filenames = {}
|
| 12 |
self.root = os.path.join(root, "debian/config")
|
| 13 |
self.config = ConfigCoreHierarchy([self.root])
|
| 14 |
|
| 15 |
self._read_base()
|
| 16 |
|
| 17 |
for key, files in self.filenames.iteritems():
|
| 18 |
r = self.setdefault(key, FileList())
|
| 19 |
for f in files:
|
| 20 |
if f in self.files:
|
| 21 |
f = self.files[f]
|
| 22 |
else:
|
| 23 |
f = self.files.setdefault(f, File(file(os.path.join(self.root, f)), f))
|
| 24 |
r.append_file(f)
|
| 25 |
|
| 26 |
def _read_arch(self, arch):
|
| 27 |
config_entry = self.config.merge('base', arch)
|
| 28 |
self.kernelarch[arch,] = config_entry.get('kernel-arch', arch)
|
| 29 |
|
| 30 |
kconfig = self.check_config("%s/config" % arch, True, arch)
|
| 31 |
self.filenames[arch,] = kconfig
|
| 32 |
|
| 33 |
for featureset in self.config['base', arch]['featuresets']:
|
| 34 |
self._read_featureset(arch, featureset)
|
| 35 |
|
| 36 |
def _read_base(self):
|
| 37 |
self.kernelarch[()] = None
|
| 38 |
self.filenames[()] = self.check_config('config', True)
|
| 39 |
|
| 40 |
for arch in self.config['base',]['arches']:
|
| 41 |
self._read_arch(arch)
|
| 42 |
|
| 43 |
def _read_featureset(self, arch, featureset):
|
| 44 |
# TODO
|
| 45 |
if featureset != 'none':
|
| 46 |
return
|
| 47 |
|
| 48 |
config_entry = self.config.merge('base', arch, featureset)
|
| 49 |
self.kernelarch[arch, featureset] = config_entry.get('kernel-arch', arch)
|
| 50 |
|
| 51 |
kconfig = []
|
| 52 |
kconfig.extend(self.check_config("featureset-%s/config" % featureset, False, None, featureset))
|
| 53 |
kconfig.extend(self.check_config("%s/%s/config" % (arch, featureset), False, arch, featureset))
|
| 54 |
self.filenames[arch, featureset] = kconfig
|
| 55 |
|
| 56 |
for flavour in self.config['base', arch, featureset]['flavours']:
|
| 57 |
self._read_flavour(arch, featureset, flavour)
|
| 58 |
|
| 59 |
def _read_flavour(self, arch, featureset, flavour):
|
| 60 |
config_entry = self.config.merge('base', arch, featureset, flavour)
|
| 61 |
self.kernelarch[arch, featureset, flavour] = config_entry.get('kernel-arch', arch)
|
| 62 |
|
| 63 |
kconfig = []
|
| 64 |
kconfig.extend(self.check_config("%s/config.%s" % (arch, flavour), False, arch, None, flavour))
|
| 65 |
kconfig.extend(self.check_config("%s/%s/config.%s" % (arch, featureset, flavour), False, arch, featureset, flavour))
|
| 66 |
self.filenames[arch, featureset, flavour] = kconfig
|
| 67 |
|
| 68 |
def _get_config(self, *entry_name):
|
| 69 |
entry_real = ('image',) + entry_name
|
| 70 |
entry = self.config.get(entry_real, None)
|
| 71 |
if entry is None:
|
| 72 |
return None
|
| 73 |
return entry.get('configs', None)
|
| 74 |
|
| 75 |
def check_config_default(self, fail, f):
|
| 76 |
f1 = self.root + '/' + f
|
| 77 |
if os.path.exists(f1):
|
| 78 |
return [f]
|
| 79 |
if fail:
|
| 80 |
raise RuntimeError("%s unavailable" % f)
|
| 81 |
return []
|
| 82 |
|
| 83 |
def check_config_files(self, files):
|
| 84 |
ret = []
|
| 85 |
for f in files:
|
| 86 |
f1 = self.root + '/' + f
|
| 87 |
if os.path.exists(f1):
|
| 88 |
ret.append(f)
|
| 89 |
break
|
| 90 |
else:
|
| 91 |
raise RuntimeError("%s unavailable" % f)
|
| 92 |
return ret
|
| 93 |
|
| 94 |
def check_config(self, default, fail, *entry_name):
|
| 95 |
configs = self._get_config(*entry_name)
|
| 96 |
if configs is None:
|
| 97 |
return self.check_config_default(fail, default)
|
| 98 |
return self.check_config_files(configs)
|
| 99 |
|
| 100 |
class FileList(object):
|
| 101 |
def __init__(self):
|
| 102 |
self._files = []
|
| 103 |
|
| 104 |
def append_file(self, item):
|
| 105 |
self._files.append(item)
|
| 106 |
|
| 107 |
class File(dict):
|
| 108 |
def __init__(self, fd, filename):
|
| 109 |
self.filename = filename
|
| 110 |
|
| 111 |
self.read(fd)
|
| 112 |
|
| 113 |
def _dump_file(self, processed, f):
|
| 114 |
ret = []
|
| 115 |
for i in f:
|
| 116 |
if isinstance(i, FileConfig):
|
| 117 |
e = self.get(i.name, None)
|
| 118 |
if e is not None:
|
| 119 |
processed.add(i.name)
|
| 120 |
ret.append(e)
|
| 121 |
if ret:
|
| 122 |
ret[0:0] = ["##", "## file: %s" % f.filename, "##"]
|
| 123 |
ret.append('')
|
| 124 |
return ret
|
| 125 |
|
| 126 |
def dump(self, root, menufiles):
|
| 127 |
filename = os.path.join(root, self.filename)
|
| 128 |
if not os.path.exists(os.path.dirname(filename)):
|
| 129 |
os.makedirs(os.path.dirname(filename))
|
| 130 |
fd = file(filename, 'w')
|
| 131 |
|
| 132 |
ret = []
|
| 133 |
processed = set()
|
| 134 |
for f in menufiles:
|
| 135 |
ret.extend(self._dump_file(processed, f))
|
| 136 |
|
| 137 |
s = set(self.keys())
|
| 138 |
unprocessed = s - processed
|
| 139 |
if unprocessed:
|
| 140 |
ret.extend(["##", "## file: unknown", "##"])
|
| 141 |
for i in unprocessed:
|
| 142 |
e = self.get(i)
|
| 143 |
ret.append(e)
|
| 144 |
ret.append('')
|
| 145 |
|
| 146 |
for i in ret:
|
| 147 |
fd.write(str(i) + "\n")
|
| 148 |
|
| 149 |
def read(self, f):
|
| 150 |
for line in iter(f.readlines()):
|
| 151 |
line = line.strip()
|
| 152 |
if line.startswith("CONFIG_"):
|
| 153 |
i = line.find('=')
|
| 154 |
option = line[7:i]
|
| 155 |
value = line[i+1:]
|
| 156 |
if value in ('y', 'm'):
|
| 157 |
entry = FileEntryTristate(option, value)
|
| 158 |
else:
|
| 159 |
entry = FileEntryString(option, value)
|
| 160 |
self[option] = entry
|
| 161 |
elif line.startswith("# CONFIG_"):
|
| 162 |
option = line[9:-11]
|
| 163 |
self[option] = FileEntryTristate(option)
|
| 164 |
elif line.startswith("#") or not line:
|
| 165 |
pass
|
| 166 |
else:
|
| 167 |
raise RuntimeError, "Can't recognize %s" % line
|
| 168 |
|
| 169 |
# TODO
|
| 170 |
class FileEntryString(object):
|
| 171 |
__slots__ = "name", "value"
|
| 172 |
|
| 173 |
def __init__(self, name, value):
|
| 174 |
self.name = name
|
| 175 |
self.value = value
|
| 176 |
|
| 177 |
def __str__(self):
|
| 178 |
return "CONFIG_%s=%s" % (self.name, self.value)
|
| 179 |
|
| 180 |
# TODO
|
| 181 |
class FileEntryTristate(object):
|
| 182 |
__slots__ = "name", "value"
|
| 183 |
|
| 184 |
VALUE_NO = 0
|
| 185 |
VALUE_YES = 1
|
| 186 |
VALUE_MOD = 2
|
| 187 |
|
| 188 |
def __init__(self, name, value = None):
|
| 189 |
self.name = name
|
| 190 |
if value == 'n' or value is None:
|
| 191 |
self.value = self.VALUE_NO
|
| 192 |
elif value == 'y':
|
| 193 |
self.value = self.VALUE_YES
|
| 194 |
elif value == 'm':
|
| 195 |
self.value = self.VALUE_MOD
|
| 196 |
|
| 197 |
def __str__(self):
|
| 198 |
conf = "CONFIG_%s" % self.name
|
| 199 |
if self.value == self.VALUE_NO:
|
| 200 |
return "# %s is not set" % conf
|
| 201 |
elif self.value == self.VALUE_YES:
|
| 202 |
return "%s=y" % conf
|
| 203 |
elif self.value == self.VALUE_MOD:
|
| 204 |
return "%s=m" % conf
|
| 205 |
|