source: mainline/tools/config.py@ d43d2f7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d43d2f7 was 795ff98, checked in by Ondrej Palkovsky <ondrap@…>, 20 years ago

Added conditions to config system.

  • Property mode set to 100755
File size: 8.7 KB
Line 
1#!/usr/bin/env python
2"""
3Kernel configuration script
4"""
5import sys
6import os
7import re
8
9INPUT = 'kernel.config'
10OUTPUT = 'Makefile.config'
11TMPOUTPUT = 'Makefile.config.tmp'
12
13class DefaultDialog:
14 "Wrapper dialog that tries to return default values"
15 def __init__(self, dlg):
16 self.dlg = dlg
17
18 def set_title(self,text):
19 self.dlg.set_title(text)
20
21 def yesno(self, text, default=None):
22 if default is not None:
23 return default
24 return self.dlg.yesno(text, default)
25 def noyes(self, text, default=None):
26 if default is not None:
27 return default
28 return self.dlg.noyes(text, default)
29
30 def choice(self, text, choices, defopt=None):
31 if defopt is not None:
32 return choices[defopt][0]
33 return self.dlg.choice(text, choices, defopt)
34
35class NoDialog:
36 def __init__(self):
37 self.printed = None
38 self.title = 'HelenOS Configuration'
39
40 def print_title(self):
41 if not self.printed:
42 sys.stdout.write("*** %s ***\n" % self.title)
43 self.printed = True
44
45 def set_title(self, text):
46 self.title = text
47 self.printed = False
48
49 def noyes(self, text, default=None):
50 if not default:
51 default = 'n'
52 return self.yesno(text, default)
53
54 def yesno(self, text, default=None):
55 self.print_title()
56
57 if default != 'n':
58 default = 'y'
59 while 1:
60 sys.stdout.write("%s (y/n)[%s]: " % (text,default))
61 inp = sys.stdin.readline()
62 if not inp:
63 raise EOFError
64 inp = inp.strip().lower()
65 if not inp:
66 return default
67 if inp == 'y':
68 return 'y'
69 elif inp == 'n':
70 return 'n'
71
72 def _print_choice(self, text, choices, defopt):
73 sys.stdout.write('%s:\n' % text)
74 for i,(text,descr) in enumerate(choices):
75 sys.stdout.write('\t%2d. %s\n' % (i, descr))
76 if defopt is not None:
77 sys.stdout.write('Enter choice number[%d]: ' % defopt)
78 else:
79 sys.stdout.write('Enter choice number: ')
80
81 def choice(self, text, choices, defopt=None):
82 self.print_title()
83 while 1:
84 self._print_choice(text, choices, defopt)
85 inp = sys.stdin.readline()
86 if not inp:
87 raise EOFError
88 if not inp.strip():
89 if defopt is not None:
90 return choices[defopt][0]
91 continue
92 try:
93 number = int(inp.strip())
94 except ValueError:
95 continue
96 if number < 0 or number >= len(choices):
97 continue
98 return choices[number][0]
99
100
101class Dialog(NoDialog):
102 def __init__(self):
103 NoDialog.__init__(self)
104 self.dlgcmd = os.environ.get('DIALOG','dialog')
105 self.title = 'HelenOS Configuration'
106
107 if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0:
108 raise NotImplementedError
109
110 def set_title(self,text):
111 self.title = text
112
113 def calldlg(self,*args,**kw):
114 indesc, outdesc = os.pipe()
115 pid = os.fork()
116 if not pid:
117 os.close(2)
118 os.dup(outdesc)
119 os.close(indesc)
120
121 dlgargs = [self.dlgcmd,'--title',self.title]
122 for key,val in kw.items():
123 dlgargs.append('--'+key)
124 dlgargs.append(val)
125 dlgargs += args
126 os.execlp(self.dlgcmd,*dlgargs)
127
128 os.close(outdesc)
129 errout = os.fdopen(indesc,'r')
130 data = errout.read()
131 errout.close()
132
133 pid,status = os.wait()
134 if not os.WIFEXITED(status):
135 raise EOFError
136 status = os.WEXITSTATUS(status)
137 if status == 255:
138 raise EOFError
139 return status,data
140
141 def yesno(self, text, default=None):
142 text = text + ':'
143 width = '50'
144 height = '5'
145 if len(text) < 48:
146 text = ' '*int(((48-len(text))/2)) + text
147 else:
148 width = '0'
149 height = '0'
150 if default == 'n':
151 res,data = self.calldlg('--defaultno','--yesno',text,height,width)
152 else:
153 res,data = self.calldlg('--yesno',text,height,width)
154
155 if res == 0:
156 return 'y'
157 return 'n'
158
159 def choice(self, text, choices, defopt=None):
160 text = text + ':'
161 width = '50'
162 height = str(8 + len(choices))
163 args = []
164 for key,val in choices:
165 args.append(key)
166 args.append(val)
167
168 kw = {}
169 if defopt:
170 kw['default-item'] = choices[defopt][0]
171 res,data = self.calldlg('--nocancel','--menu',text,height,width,
172 str(len(choices)),*args, **kw)
173 if res:
174 print data
175 raise EOFError
176 return data
177
178def read_defaults(fname,defaults):
179 f = file(fname,'r')
180 for line in f:
181 res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
182 if res:
183 defaults[res.group(1)] = res.group(2)
184 f.close()
185
186def check_condition(text, defaults):
187 result = False
188 conds = text.split('|')
189 for cond in conds:
190 condname,condval = cond.split('=')
191 if not defaults.has_key(condname):
192 raise RuntimeError("Condition var %s does not exist: %s" % \
193 (condname,line))
194 # None means wildcard
195 if defaults[condname] is None:
196 return True
197 if condval == defaults[condname]:
198 return True
199 return False
200
201def parse_config(input, output, dlg, defaults={}):
202 f = file(input, 'r')
203 outf = file(output, 'w')
204
205 outf.write('#########################################\n')
206 outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
207 outf.write('#########################################\n\n')
208
209 comment = ''
210 default = None
211 choices = []
212 for line in f:
213 if line.startswith('!'):
214 res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
215 if not res:
216 raise RuntimeError("Weird line: %s" % line)
217 varname = res.group(2)
218 vartype = res.group(3)
219
220 default = defaults.get(varname,None)
221
222 if res.group(1):
223 if not check_condition(res.group(1), defaults):
224 if default is not None:
225 outf.write('#!# %s = %s\n' % (varname, default))
226 continue
227
228 if vartype == 'y/n':
229 result = dlg.yesno(comment, default)
230 elif vartype == 'n/y':
231 result = dlg.noyes(comment, default)
232 elif vartype == 'choice':
233 defopt = None
234 if default is not None:
235 for i,(key,val) in enumerate(choices):
236 if key == default:
237 defopt = i
238 break
239 result = dlg.choice(comment, choices, defopt)
240 else:
241 raise RuntimeError("Bad method: %s" % vartype)
242 outf.write('%s = %s\n' % (varname, result))
243 # Remeber the selected value
244 defaults[varname] = result
245 # Clear cumulated values
246 comment = ''
247 default = None
248 choices = []
249 continue
250
251 if line.startswith('@'):
252 res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
253 if not res:
254 raise RuntimeError("Bad line: %s" % line)
255 if res.group(1):
256 if not check_condition(res.group(1),defaults):
257 continue
258 choices.append((res.group(2), res.group(3)))
259 continue
260
261 outf.write(line)
262 if re.match(r'^#[^#]', line):
263 comment = line[1:].strip()
264 elif line.startswith('##'):
265 dlg.set_title(line[2:].strip())
266
267 outf.close()
268 f.close()
269
270def main():
271 defaults = {'ARCH':None}
272 try:
273 dlg = Dialog()
274 except NotImplementedError:
275 dlg = NoDialog()
276
277 # Default run will update the configuration file
278 # with newest options
279 if len(sys.argv) >= 2:
280 defaults['ARCH'] = sys.argv[1]
281 if len(sys.argv) == 3 and sys.argv[2]=='default':
282 dlg = DefaultDialog(dlg)
283
284 if os.path.exists(OUTPUT):
285 read_defaults(OUTPUT, defaults)
286
287 parse_config(INPUT, TMPOUTPUT, dlg, defaults)
288 if os.path.exists(OUTPUT):
289 os.unlink(OUTPUT)
290 os.rename(TMPOUTPUT, OUTPUT)
291
292
293if __name__ == '__main__':
294 main()
Note: See TracBrowser for help on using the repository browser.