Subversion Repositories HelenOS-historic

Rev

Rev 558 | Rev 560 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 558 Rev 559
1
#!/usr/bin/env python
1
#!/usr/bin/env python
2
"""
2
"""
3
Kernel configuration script
3
Kernel configuration script
4
"""
4
"""
5
import sys
5
import sys
6
import os
6
import os
7
import re
7
import re
8
 
8
 
9
INPUT = 'kernel.config'
9
INPUT = 'kernel.config'
10
OUTPUT = 'Makefile.config'
10
OUTPUT = 'Makefile.config'
11
TMPOUTPUT = 'Makefile.config.tmp'
11
TMPOUTPUT = 'Makefile.config.tmp'
12
 
12
 
13
class DefaultDialog:
13
class DefaultDialog:
14
    "Wrapper dialog that tries to return default values"
14
    "Wrapper dialog that tries to return default values"
15
    def __init__(self, dlg):
15
    def __init__(self, dlg):
16
        self.dlg = dlg
16
        self.dlg = dlg
17
 
17
 
18
    def set_title(self,text):
18
    def set_title(self,text):
19
        self.dlg.set_title(text)
19
        self.dlg.set_title(text)
20
       
20
       
21
    def yesno(self, text, default=None):
21
    def yesno(self, text, default=None):
22
        if default is not None:
22
        if default is not None:
23
            return default
23
            return default
24
        return self.dlg.yesno(text, default)
24
        return self.dlg.yesno(text, default)
25
    def noyes(self, text, default=None):
25
    def noyes(self, text, default=None):
26
        if default is not None:
26
        if default is not None:
27
            return default
27
            return default
28
        return self.dlg.noyes(text, default)
28
        return self.dlg.noyes(text, default)
29
   
29
   
30
    def choice(self, text, choices, defopt=None):
30
    def choice(self, text, choices, defopt=None):
31
        if defopt is not None:
31
        if defopt is not None:
32
            return choices[defopt][0]
32
            return choices[defopt][0]
33
        return self.dlg.choice(text, choices, defopt)
33
        return self.dlg.choice(text, choices, defopt)
34
 
34
 
35
class NoDialog:
35
class NoDialog:
36
    def __init__(self):
36
    def __init__(self):
37
        self.printed = None
37
        self.printed = None
38
        self.title = 'HelenOS Configuration'
38
        self.title = 'HelenOS Configuration'
39
 
39
 
40
    def print_title(self):
40
    def print_title(self):
41
        if not self.printed:
41
        if not self.printed:
42
            sys.stdout.write("\n*** %s ***\n" % self.title)
42
            sys.stdout.write("\n*** %s ***\n" % self.title)
43
            self.printed = True
43
            self.printed = True
44
 
44
 
45
    def set_title(self, text):
45
    def set_title(self, text):
46
        self.title = text
46
        self.title = text
47
        self.printed = False
47
        self.printed = False
48
   
48
   
49
    def noyes(self, text, default=None):
49
    def noyes(self, text, default=None):
50
        if not default:
50
        if not default:
51
            default = 'n'
51
            default = 'n'
52
        return self.yesno(text, default)
52
        return self.yesno(text, default)
53
   
53
   
54
    def yesno(self, text, default=None):
54
    def yesno(self, text, default=None):
55
        self.print_title()
55
        self.print_title()
56
       
56
       
57
        if default != 'n':
57
        if default != 'n':
58
            default = 'y'
58
            default = 'y'
59
        while 1:
59
        while 1:
60
            sys.stdout.write("%s (y/n)[%s]: " % (text,default))
60
            sys.stdout.write("%s (y/n)[%s]: " % (text,default))
61
            inp = sys.stdin.readline()
61
            inp = sys.stdin.readline()
62
            if not inp:
62
            if not inp:
63
                raise EOFError
63
                raise EOFError
64
            inp = inp.strip().lower()
64
            inp = inp.strip().lower()
65
            if not inp:
65
            if not inp:
66
                return default
66
                return default
67
            if inp == 'y':
67
            if inp == 'y':
68
                return 'y'
68
                return 'y'
69
            elif inp == 'n':
69
            elif inp == 'n':
70
                return 'n'
70
                return 'n'
71
 
71
 
72
    def _print_choice(self, text, choices, defopt):
72
    def _print_choice(self, text, choices, defopt):
73
        sys.stdout.write('%s:\n' % text)
73
        sys.stdout.write('%s:\n' % text)
74
        for i,(text,descr) in enumerate(choices):
74
        for i,(text,descr) in enumerate(choices):
75
            sys.stdout.write('\t%2d. %s\n' % (i, descr))
75
            sys.stdout.write('\t%2d. %s\n' % (i, descr))
76
        if defopt is not None:
76
        if defopt is not None:
77
            sys.stdout.write('Enter choice number[%d]: ' % defopt)
77
            sys.stdout.write('Enter choice number[%d]: ' % defopt)
78
        else:
78
        else:
79
            sys.stdout.write('Enter choice number: ')
79
            sys.stdout.write('Enter choice number: ')
80
 
80
 
81
    def menu(self, text, choices, button, defopt=None):
81
    def menu(self, text, choices, button, defopt=None):
82
        menu = []
82
        menu = []
83
        for key, descr in choices:
83
        for key, descr in choices:
84
            txt = key + (45-len(key))*' ' + ': ' + descr
84
            txt = key + (45-len(key))*' ' + ': ' + descr
85
            menu.append((key, txt))
85
            menu.append((key, txt))
86
           
86
           
87
        return self.choice(text, [button] + menu)
87
        return self.choice(text, [button] + menu)
88
       
88
       
89
    def choice(self, text, choices, defopt=None):
89
    def choice(self, text, choices, defopt=None):
90
        self.print_title()
90
        self.print_title()
91
        while 1:
91
        while 1:
92
            self._print_choice(text, choices, defopt)
92
            self._print_choice(text, choices, defopt)
93
            inp = sys.stdin.readline()
93
            inp = sys.stdin.readline()
94
            if not inp:
94
            if not inp:
95
                raise EOFError
95
                raise EOFError
96
            if not inp.strip():
96
            if not inp.strip():
97
                if defopt is not None:
97
                if defopt is not None:
98
                    return choices[defopt][0]
98
                    return choices[defopt][0]
99
                continue
99
                continue
100
            try:
100
            try:
101
                number = int(inp.strip())
101
                number = int(inp.strip())
102
            except ValueError:
102
            except ValueError:
103
                continue
103
                continue
104
            if number < 0 or number >= len(choices):
104
            if number < 0 or number >= len(choices):
105
                continue
105
                continue
106
            return choices[number][0]
106
            return choices[number][0]
107
 
107
 
108
 
108
 
109
class Dialog(NoDialog):
109
class Dialog(NoDialog):
110
    def __init__(self):
110
    def __init__(self):
111
        NoDialog.__init__(self)
111
        NoDialog.__init__(self)
112
        self.dlgcmd = os.environ.get('DIALOG','dialog')
112
        self.dlgcmd = os.environ.get('DIALOG','dialog')
113
        self.title = ''
113
        self.title = ''
114
        self.backtitle = 'HelenOS Kernel Configuration'
114
        self.backtitle = 'HelenOS Kernel Configuration'
115
       
115
       
116
        if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0:
116
        if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0:
117
            raise NotImplementedError
117
            raise NotImplementedError
118
 
118
 
119
    def set_title(self,text):
119
    def set_title(self,text):
120
        self.title = text
120
        self.title = text
121
       
121
       
122
    def calldlg(self,*args,**kw):
122
    def calldlg(self,*args,**kw):
123
        "Wrapper for calling 'dialog' program"
123
        "Wrapper for calling 'dialog' program"
124
        indesc, outdesc = os.pipe()
124
        indesc, outdesc = os.pipe()
125
        pid = os.fork()
125
        pid = os.fork()
126
        if not pid:
126
        if not pid:
127
            os.close(2)
127
            os.close(2)
128
            os.dup(outdesc)
128
            os.dup(outdesc)
129
            os.close(indesc)
129
            os.close(indesc)
130
           
130
           
131
            dlgargs = [self.dlgcmd,'--title',self.title,
131
            dlgargs = [self.dlgcmd,'--title',self.title,
132
                       '--backtitle', self.backtitle]
132
                       '--backtitle', self.backtitle]
133
            for key,val in kw.items():
133
            for key,val in kw.items():
134
                dlgargs.append('--'+key)
134
                dlgargs.append('--'+key)
135
                dlgargs.append(val)
135
                dlgargs.append(val)
136
            dlgargs += args            
136
            dlgargs += args            
137
            os.execlp(self.dlgcmd,*dlgargs)
137
            os.execlp(self.dlgcmd,*dlgargs)
138
 
138
 
139
        os.close(outdesc)
139
        os.close(outdesc)
140
       
140
       
141
        try:
141
        try:
142
            errout = os.fdopen(indesc,'r')
142
            errout = os.fdopen(indesc,'r')
143
            data = errout.read()
143
            data = errout.read()
144
            errout.close()
144
            errout.close()
145
            pid,status = os.wait()
145
            pid,status = os.wait()
146
        except:
146
        except:
147
            os.system('reset') # Reset terminal
147
            os.system('reset') # Reset terminal
148
            raise
148
            raise
149
       
149
       
150
        if not os.WIFEXITED(status):
150
        if not os.WIFEXITED(status):
151
            os.system('reset') # Reset terminal
151
            os.system('reset') # Reset terminal
152
            raise EOFError
152
            raise EOFError
153
       
153
       
154
        status = os.WEXITSTATUS(status)
154
        status = os.WEXITSTATUS(status)
155
        if status == 255:
155
        if status == 255:
156
            raise EOFError
156
            raise EOFError
157
        return status,data
157
        return status,data
158
       
158
       
159
    def yesno(self, text, default=None):
159
    def yesno(self, text, default=None):
160
        if text[-1] not in ('?',':'):
160
        if text[-1] not in ('?',':'):
161
            text = text + ':'
161
            text = text + ':'
162
        width = '50'
162
        width = '50'
163
        height = '5'
163
        height = '5'
164
        if len(text) < 48:
164
        if len(text) < 48:
165
            text = ' '*int(((48-len(text))/2)) + text
165
            text = ' '*int(((48-len(text))/2)) + text
166
        else:
166
        else:
167
            width = '0'
167
            width = '0'
168
            height = '0'
168
            height = '0'
169
        if default == 'n':
169
        if default == 'n':
170
            res,data = self.calldlg('--defaultno','--yesno',text,height,width)
170
            res,data = self.calldlg('--defaultno','--yesno',text,height,width)
171
        else:
171
        else:
172
            res,data = self.calldlg('--yesno',text,height,width)
172
            res,data = self.calldlg('--yesno',text,height,width)
173
 
173
 
174
        if res == 0:
174
        if res == 0:
175
            return 'y'
175
            return 'y'
176
        return 'n'
176
        return 'n'
177
 
177
 
178
    def menu(self, text, choices, button, defopt=None):
178
    def menu(self, text, choices, button, defopt=None):
179
        text = text + ':'
179
        text = text + ':'
180
        width = '70'
180
        width = '70'
181
        height = str(8 + len(choices))
181
        height = str(8 + len(choices))
182
        args = []
182
        args = []
183
        for key,val in choices:
183
        for key,val in choices:
184
            args.append(key)
184
            args.append(key)
185
            args.append(val)
185
            args.append(val)
186
 
186
 
187
        kw = {}
187
        kw = {}
188
        if defopt:
188
        if defopt:
189
            kw['default-item'] = choices[defopt][0]
189
            kw['default-item'] = choices[defopt][0]
190
        res,data = self.calldlg('--cancel-label',button[1],
190
        res,data = self.calldlg('--extra-label',button[1],
-
 
191
                                '--extra-button',
191
                                '--menu',text,height,width,
192
                                '--menu',text,height,width,
192
                                str(len(choices)),*args,**kw)
193
                                str(len(choices)),*args,**kw)
193
        if res == 1:
194
        if res == 3:
194
            return button[0]
195
            return button[0]
-
 
196
        if res == 1: # Cancel
-
 
197
            sys.exit(1)
195
        elif res:
198
        elif res:
196
            print data
199
            print data
197
            raise EOFError
200
            raise EOFError
198
        return data
201
        return data
199
   
202
   
200
    def choice(self, text, choices, defopt=None):
203
    def choice(self, text, choices, defopt=None):
201
        text = text + ':'
204
        text = text + ':'
202
        width = '50'
205
        width = '50'
203
        height = str(8 + len(choices))
206
        height = str(8 + len(choices))
204
        args = []
207
        args = []
205
        for key,val in choices:
208
        for key,val in choices:
206
            args.append(key)
209
            args.append(key)
207
            args.append(val)
210
            args.append(val)
208
 
211
 
209
        kw = {}
212
        kw = {}
210
        if defopt:
213
        if defopt:
211
            kw['default-item'] = choices[defopt][0]
214
            kw['default-item'] = choices[defopt][0]
212
        res,data = self.calldlg('--nocancel','--menu',text,height,width,
215
        res,data = self.calldlg('--nocancel','--menu',text,height,width,
213
                                str(len(choices)),*args, **kw)
216
                                str(len(choices)),*args, **kw)
214
        if res:
217
        if res:
215
            print data
218
            print data
216
            raise EOFError
219
            raise EOFError
217
        return data
220
        return data
218
   
221
   
219
def read_defaults(fname,defaults):
222
def read_defaults(fname,defaults):
220
    "Read saved values from last configuration run"
223
    "Read saved values from last configuration run"
221
    f = file(fname,'r')
224
    f = file(fname,'r')
222
    for line in f:
225
    for line in f:
223
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
226
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
224
        if res:
227
        if res:
225
            defaults[res.group(1)] = res.group(2)
228
            defaults[res.group(1)] = res.group(2)
226
    f.close()
229
    f.close()
227
 
230
 
228
def check_condition(text, defaults):
231
def check_condition(text, defaults):
229
    result = True
232
    result = True
230
    conds = text.split('&')
233
    conds = text.split('&')
231
    for cond in conds:
234
    for cond in conds:
232
        if cond.startswith('(') and cond.endswith(')'):
235
        if cond.startswith('(') and cond.endswith(')'):
233
            cond = cond[1:-1]
236
            cond = cond[1:-1]
234
        if not check_dnf(cond, defaults):
237
        if not check_dnf(cond, defaults):
235
            return False
238
            return False
236
    return True
239
    return True
237
 
240
 
238
def check_dnf(text, defaults):
241
def check_dnf(text, defaults):
239
    """
242
    """
240
    Check that the condition specified on input line is True
243
    Check that the condition specified on input line is True
241
 
244
 
242
    only CNF is supported
245
    only CNF is supported
243
    """
246
    """
244
    conds = text.split('|')
247
    conds = text.split('|')
245
    for cond in conds:
248
    for cond in conds:
246
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
249
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
247
        if not res:
250
        if not res:
248
            raise RuntimeError("Invalid condition: %s" % cond)
251
            raise RuntimeError("Invalid condition: %s" % cond)
249
        condname = res.group(1)
252
        condname = res.group(1)
250
        oper = res.group(2)
253
        oper = res.group(2)
251
        condval = res.group(3)
254
        condval = res.group(3)
252
        if not defaults.has_key(condname):
255
        if not defaults.has_key(condname):
253
            raise RuntimeError("Condition var %s does not exist: %s" % \
256
            raise RuntimeError("Condition var %s does not exist: %s" % \
254
                               (condname,text))
257
                               (condname,text))
255
 
258
 
256
        if oper=='=' and  condval == defaults[condname]:
259
        if oper=='=' and  condval == defaults[condname]:
257
            return True
260
            return True
258
        if oper == '!=' and condval != defaults[condname]:
261
        if oper == '!=' and condval != defaults[condname]:
259
            return True
262
            return True
260
    return False
263
    return False
261
 
264
 
262
def parse_config(input, output, dlg, defaults={}, askonly=None):
265
def parse_config(input, output, dlg, defaults={}, askonly=None):
263
    "Parse configuration file and create Makefile.config on the fly"
266
    "Parse configuration file and create Makefile.config on the fly"
264
    def ask_the_question():
267
    def ask_the_question():
265
        "Ask question based on the type of variables to ask"
268
        "Ask question based on the type of variables to ask"
266
        # This is quite a hack, this thingy is written just to
269
        # This is quite a hack, this thingy is written just to
267
        # have access to local variables..
270
        # have access to local variables..
268
        if vartype == 'y/n':
271
        if vartype == 'y/n':
269
            return dlg.yesno(comment, default)
272
            return dlg.yesno(comment, default)
270
        elif vartype == 'n/y':
273
        elif vartype == 'n/y':
271
            return dlg.noyes(comment, default)
274
            return dlg.noyes(comment, default)
272
        elif vartype == 'choice':
275
        elif vartype == 'choice':
273
            defopt = None
276
            defopt = None
274
            if default is not None:
277
            if default is not None:
275
                for i,(key,val) in enumerate(choices):
278
                for i,(key,val) in enumerate(choices):
276
                    if key == default:
279
                    if key == default:
277
                        defopt = i
280
                        defopt = i
278
                        break
281
                        break
279
            return dlg.choice(comment, choices, defopt)
282
            return dlg.choice(comment, choices, defopt)
280
        else:
283
        else:
281
            raise RuntimeError("Bad method: %s" % vartype)
284
            raise RuntimeError("Bad method: %s" % vartype)
282
 
285
 
283
   
286
   
284
    f = file(input, 'r')
287
    f = file(input, 'r')
285
    outf = file(output, 'w')
288
    outf = file(output, 'w')
286
 
289
 
287
    outf.write('#########################################\n')
290
    outf.write('#########################################\n')
288
    outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
291
    outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
289
    outf.write('#########################################\n\n')
292
    outf.write('#########################################\n\n')
290
 
293
 
291
    asked_names = []
294
    asked_names = []
292
 
295
 
293
    comment = ''
296
    comment = ''
294
    default = None
297
    default = None
295
    choices = []
298
    choices = []
296
    for line in f:
299
    for line in f:
297
        if line.startswith('%'):
300
        if line.startswith('%'):
298
            res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
301
            res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
299
            if not res:
302
            if not res:
300
                raise RuntimeError('Invalid command: %s' % line)
303
                raise RuntimeError('Invalid command: %s' % line)
301
            if res.group(1):
304
            if res.group(1):
302
                if not check_condition(res.group(1), defaults):
305
                if not check_condition(res.group(1), defaults):
303
                    continue
306
                    continue
304
            args = res.group(2).strip().split(' ')
307
            args = res.group(2).strip().split(' ')
305
            cmd = args[0].lower()
308
            cmd = args[0].lower()
306
            args = args[1:]
309
            args = args[1:]
307
            if cmd == 'saveas':
310
            if cmd == 'saveas':
308
                outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
311
                outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
309
               
312
               
310
            continue
313
            continue
311
           
314
           
312
        if line.startswith('!'):
315
        if line.startswith('!'):
313
            # Ask a question
316
            # Ask a question
314
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
317
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
315
            if not res:
318
            if not res:
316
                raise RuntimeError("Weird line: %s" % line)
319
                raise RuntimeError("Weird line: %s" % line)
317
            varname = res.group(2)
320
            varname = res.group(2)
318
            vartype = res.group(3)
321
            vartype = res.group(3)
319
 
322
 
320
            default = defaults.get(varname,None)
323
            default = defaults.get(varname,None)
321
           
324
           
322
            if res.group(1):
325
            if res.group(1):
323
                if not check_condition(res.group(1), defaults):
326
                if not check_condition(res.group(1), defaults):
324
                    if default is not None:
327
                    if default is not None:
325
                        outf.write('#!# %s = %s\n' % (varname, default))
328
                        outf.write('#!# %s = %s\n' % (varname, default))
326
                    # Clear cumulated values
329
                    # Clear cumulated values
327
                    comment = ''
330
                    comment = ''
328
                    default = None
331
                    default = None
329
                    choices = []
332
                    choices = []
330
                    continue
333
                    continue
331
               
334
               
332
            asked_names.append((varname,comment))
335
            asked_names.append((varname,comment))
333
 
336
 
334
            if default is None or not askonly or askonly == varname:
337
            if default is None or not askonly or askonly == varname:
335
                default = ask_the_question()
338
                default = ask_the_question()
336
 
339
 
337
            outf.write('%s = %s\n' % (varname, default))
340
            outf.write('%s = %s\n' % (varname, default))
338
            # Remeber the selected value
341
            # Remeber the selected value
339
            defaults[varname] = default
342
            defaults[varname] = default
340
            # Clear cumulated values
343
            # Clear cumulated values
341
            comment = ''
344
            comment = ''
342
            default = None
345
            default = None
343
            choices = []
346
            choices = []
344
            continue
347
            continue
345
       
348
       
346
        if line.startswith('@'):
349
        if line.startswith('@'):
347
            # Add new line into the 'choice array' 
350
            # Add new line into the 'choice array' 
348
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
351
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
349
            if not res:
352
            if not res:
350
                raise RuntimeError("Bad line: %s" % line)
353
                raise RuntimeError("Bad line: %s" % line)
351
            if res.group(1):
354
            if res.group(1):
352
                if not check_condition(res.group(1),defaults):
355
                if not check_condition(res.group(1),defaults):
353
                    continue
356
                    continue
354
            choices.append((res.group(2), res.group(3)))
357
            choices.append((res.group(2), res.group(3)))
355
            continue
358
            continue
356
 
359
 
357
        # All other things print to output file
360
        # All other things print to output file
358
        outf.write(line)
361
        outf.write(line)
359
        if re.match(r'^#[^#]', line):
362
        if re.match(r'^#[^#]', line):
360
            # Last comment before question will be displayed to the user
363
            # Last comment before question will be displayed to the user
361
            comment = line[1:].strip()
364
            comment = line[1:].strip()
362
        elif line.startswith('## '):
365
        elif line.startswith('## '):
363
            # Set title of the dialog window
366
            # Set title of the dialog window
364
            dlg.set_title(line[2:].strip())
367
            dlg.set_title(line[2:].strip())
365
       
368
       
366
    outf.close()
369
    outf.close()
367
    f.close()
370
    f.close()
368
    return asked_names
371
    return asked_names
369
 
372
 
370
def main():
373
def main():
371
    defaults = {}
374
    defaults = {}
372
    try:
375
    try:
373
        dlg = Dialog()
376
        dlg = Dialog()
374
    except NotImplementedError:
377
    except NotImplementedError:
375
        dlg = NoDialog()
378
        dlg = NoDialog()
376
 
379
 
377
    if len(sys.argv) == 2 and sys.argv[1]=='default':
380
    if len(sys.argv) == 2 and sys.argv[1]=='default':
378
        defmode = True
381
        defmode = True
379
    else:
382
    else:
380
        defmode = False
383
        defmode = False
381
 
384
 
382
    # Default run will update the configuration file
385
    # Default run will update the configuration file
383
    # with newest options
386
    # with newest options
384
    if os.path.exists(OUTPUT):
387
    if os.path.exists(OUTPUT):
385
        read_defaults(OUTPUT, defaults)
388
        read_defaults(OUTPUT, defaults)
386
 
389
 
387
    # Dry run only with defaults
390
    # Dry run only with defaults
388
    varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
391
    varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
389
    # If not in default mode, present selection of all possibilities
392
    # If not in default mode, present selection of all possibilities
390
    if not defmode:
393
    if not defmode:
391
        defopt = 0
394
        defopt = 0
392
        while 1:
395
        while 1:
393
            # varnames contains variable names that were in the
396
            # varnames contains variable names that were in the
394
            # last question set
397
            # last question set
395
            choices = [ (x[1],defaults[x[0]]) for x in varnames ]
398
            choices = [ (x[1],defaults[x[0]]) for x in varnames ]
396
            res = dlg.menu('Configuration',choices,('save','Save'),defopt)
399
            res = dlg.menu('Configuration',choices,('save','Save'),defopt)
397
            if res == 'save':
400
            if res == 'save':
398
                parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
401
                parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
399
                break
402
                break
400
            # transfer description back to varname
403
            # transfer description back to varname
401
            for i,(vname,descr) in enumerate(varnames):
404
            for i,(vname,descr) in enumerate(varnames):
402
                if res == descr:
405
                if res == descr:
403
                    defopt = i
406
                    defopt = i
404
                    break
407
                    break
405
            # Ask the user a simple question, produce output
408
            # Ask the user a simple question, produce output
406
            # as if the user answered all the other questions
409
            # as if the user answered all the other questions
407
            # with default answer
410
            # with default answer
408
            varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
411
            varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
409
                                    askonly=varnames[i][0])
412
                                    askonly=varnames[i][0])
410
       
413
       
411
   
414
   
412
    if os.path.exists(OUTPUT):
415
    if os.path.exists(OUTPUT):
413
        os.unlink(OUTPUT)
416
        os.unlink(OUTPUT)
414
    os.rename(TMPOUTPUT, OUTPUT)
417
    os.rename(TMPOUTPUT, OUTPUT)
415
   
418
   
416
    if not defmode and dlg.yesno('Rebuild kernel?') == 'y':
419
    if not defmode and dlg.yesno('Rebuild kernel?') == 'y':
417
        os.execlp('make','make','clean','all')
420
        os.execlp('make','make','clean','all')
418
 
421
 
419
if __name__ == '__main__':
422
if __name__ == '__main__':
420
    main()
423
    main()
421
 
424