upload tizen1.0 source
[kernel/linux-2.6.36.git] / debian / lib / python / debian_linux / config.py
1 import os, os.path, re, sys, textwrap
2
3 __all__ = [
4     'ConfigCoreDump',
5     'ConfigCoreHierarchy',
6     'ConfigParser',
7 ]
8
9 class SchemaItemBoolean(object):
10     def __call__(self, i):
11         i = i.strip().lower()
12         if i in ("true", "1"):
13             return True
14         if i in ("false", "0"):
15             return False
16         raise Error
17
18 class SchemaItemList(object):
19     def __init__(self, type = "\s+"):
20         self.type = type
21
22     def __call__(self, i):
23         i = i.strip()
24         if not i:
25             return []
26         return [j.strip() for j in re.split(self.type, i)]
27
28 class ConfigCore(dict):
29     def get_merge(self, section, arch, featureset, flavour, key, default=None):
30         temp = []
31
32         if arch and featureset and flavour:
33             temp.append(self.get((section, arch, featureset, flavour), {}).get(key))
34             temp.append(self.get((section, arch, None, flavour), {}).get(key))
35         if arch and featureset:
36             temp.append(self.get((section, arch, featureset), {}).get(key))
37         if arch:
38             temp.append(self.get((section, arch), {}).get(key))
39         if featureset:
40             temp.append(self.get((section, None, featureset), {}).get(key))
41         temp.append(self.get((section,), {}).get(key))
42
43         ret = []
44
45         for i in temp:
46             if i is None:
47                 continue
48             elif isinstance(i, (list, tuple)):
49                 ret.extend(i)
50             elif ret:
51                 # TODO
52                 return ret
53             else:
54                 return i
55
56         return ret or default
57
58     def merge(self, section, arch = None, featureset = None, flavour = None):
59         ret = {}
60         ret.update(self.get((section,), {}))
61         if featureset:
62             ret.update(self.get((section, None, featureset), {}))
63         if arch:
64             ret.update(self.get((section, arch), {}))
65         if arch and featureset:
66             ret.update(self.get((section, arch, featureset), {}))
67         if arch and featureset and flavour:
68             ret.update(self.get((section, arch, None, flavour), {}))
69             ret.update(self.get((section, arch, featureset, flavour), {}))
70         return ret
71
72     def dump(self, fp):
73         sections = self.keys()
74         sections.sort()
75         for section in sections:
76             fp.write('[%r]\n' % (section,))
77             items = self[section]
78             items_keys = items.keys()
79             items_keys.sort()
80             for item in items:
81                 fp.write('%s: %r\n' % (item, items[item]))
82             fp.write('\n')
83
84 class ConfigCoreDump(ConfigCore):
85     def __init__(self, config = None, fp = None):
86         super(ConfigCoreDump, self).__init__(self)
87         if config is not None:
88             self.update(config)
89         if fp is not None:
90             from ConfigParser import RawConfigParser
91             config = RawConfigParser()
92             config.readfp(fp)
93             for section in config.sections():
94                 section_real = eval(section)
95                 data = {}
96                 for key, value in config.items(section):
97                     value_real = eval(value)
98                     data[key] = value_real
99                 self[section_real] = data
100
101 class ConfigCoreHierarchy(ConfigCore):
102     config_name = "defines"
103
104     schemas = {
105         'abi': {
106             'ignore-changes': SchemaItemList(),
107         },
108         'base': {
109             'arches': SchemaItemList(),
110             'enabled': SchemaItemBoolean(),
111             'featuresets': SchemaItemList(),
112             'flavours': SchemaItemList(),
113             'modules': SchemaItemBoolean(),
114         },
115         'build': {},
116         'description': {
117             'parts': SchemaItemList(),
118         },
119         'image': {
120             'configs': SchemaItemList(),
121             'initramfs': SchemaItemBoolean(),
122             'initramfs-generators': SchemaItemList(),
123         },
124         'image-dbg': {
125             'enabled': SchemaItemBoolean(),
126         },
127         'relations': {
128         },
129         'xen': {
130             'dom0-support': SchemaItemBoolean(),
131             'flavours': SchemaItemList(),
132             'versions': SchemaItemList(),
133         }
134     }
135
136     def __init__(self, dirs = []):
137         super(ConfigCoreHierarchy, self).__init__()
138         self._dirs = dirs
139         self._read_base()
140
141     def _read_arch(self, arch):
142         config = ConfigParser(self.schemas)
143         config.read(self.get_files("%s/%s" % (arch, self.config_name)))
144
145         featuresets = config['base',].get('featuresets', [])
146         flavours = config['base',].get('flavours', [])
147
148         for section in iter(config):
149             if section[0] in featuresets:
150                 real = (section[-1], arch, section[0])
151             elif len(section) > 1:
152                 real = (section[-1], arch, None) + section[:-1]
153             else:
154                 real = (section[-1], arch) + section[:-1]
155             s = self.get(real, {})
156             s.update(config[section])
157             self[tuple(real)] = s
158
159         for featureset in featuresets:
160             self._read_arch_featureset(arch, featureset)
161
162         if flavours:
163             base = self['base', arch]
164             featuresets.insert(0, 'none')
165             base['featuresets'] = featuresets
166             del base['flavours']
167             self['base', arch] = base
168             self['base', arch, 'none'] = {'flavours': flavours, 'implicit-flavour': True}
169
170     def _read_arch_featureset(self, arch, featureset):
171         config = ConfigParser(self.schemas)
172         config.read(self.get_files("%s/%s/%s" % (arch, featureset, self.config_name)))
173
174         flavours = config['base',].get('flavours', [])
175
176         for section in iter(config):
177             real = (section[-1], arch, featureset) + section[:-1]
178             s = self.get(real, {})
179             s.update(config[section])
180             self[tuple(real)] = s
181
182     def _read_base(self):
183         config = ConfigParser(self.schemas)
184         config.read(self.get_files(self.config_name))
185
186         arches = config['base',]['arches']
187         featuresets = config['base',].get('featuresets', [])
188
189         for section in iter(config):
190             if section[0].startswith('featureset-'):
191                 real = (section[-1], None, section[0].lstrip('featureset-'))
192             else:
193                 real = (section[-1],) + section[1:]
194             self[real] = config[section]
195
196         for arch in arches:
197             self._read_arch(arch)
198         for featureset in featuresets:
199             self._read_featureset(featureset)
200
201     def _read_featureset(self, featureset):
202         config = ConfigParser(self.schemas)
203         config.read(self.get_files("featureset-%s/%s" % (featureset, self.config_name)))
204
205         for section in iter(config):
206             real = (section[-1], None, featureset)
207             s = self.get(real, {})
208             s.update(config[section])
209             self[real] = s
210
211     def get_files(self, name):
212         return [os.path.join(i, name) for i in self._dirs if i]
213
214 class ConfigParser(object):
215     __slots__ = '_config', 'schemas'
216
217     def __init__(self, schemas):
218         self.schemas = schemas
219
220         from ConfigParser import RawConfigParser
221         self._config = config = RawConfigParser()
222
223     def __getitem__(self, key):
224         return self._convert()[key]
225
226     def __iter__(self):
227         return iter(self._convert())
228
229     def __str__(self):
230         return '<%s(%s)>' % (self.__class__.__name__, self._convert())
231
232     def _convert(self):
233         ret = {}
234         for section in self._config.sections():
235             data = {}
236             for key, value in self._config.items(section):
237                 data[key] = value
238             s1 = section.split('_')
239             if s1[-1] in self.schemas:
240                 ret[tuple(s1)] = self.SectionSchema(data, self.schemas[s1[-1]])
241             else:
242                 ret[(section,)] = self.Section(data)
243         return ret
244
245     def keys(self):
246         return self._convert().keys()
247
248     def read(self, data):
249         return self._config.read(data)
250
251     class Section(dict):
252         def __init__(self, data):
253             super(ConfigParser.Section, self).__init__(data)
254
255     class SectionSchema(Section):
256         __slots__ = ()
257
258         def __init__(self, data, schema):
259             for key in data.keys():
260                 try:
261                     data[key] = schema[key](data[key])
262                 except KeyError: pass
263             super(ConfigParser.SectionSchema, self).__init__(data)
264
265 if __name__ == '__main__':
266     import sys
267     config = ConfigCoreHierarchy(['debian/config'])
268     sections = config.keys()
269     sections.sort()
270     for section in sections:
271         print "[%s]" % (section,)
272         items = config[section]
273         items_keys = items.keys()
274         items_keys.sort()
275         for item in items:
276             print "%s: %s" % (item, items[item])
277         print
278