Subversion Repositories HelenOS-historic

Rev

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

Rev 555 Rev 556
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
        errout = os.fdopen(indesc,'r')
140
        errout = os.fdopen(indesc,'r')
141
        data = errout.read()
141
        data = errout.read()
142
        errout.close()
142
        errout.close()
143
           
143
           
144
        pid,status = os.wait()
144
        pid,status = os.wait()
145
        if not os.WIFEXITED(status):
145
        if not os.WIFEXITED(status):
146
            raise EOFError
146
            raise EOFError
147
        status = os.WEXITSTATUS(status)
147
        status = os.WEXITSTATUS(status)
148
        if status == 255:
148
        if status == 255:
149
            raise EOFError
149
            raise EOFError
150
        return status,data
150
        return status,data
151
       
151
       
152
    def yesno(self, text, default=None):
152
    def yesno(self, text, default=None):
153
        text = text + ':'
153
        text = text + ':'
154
        width = '50'
154
        width = '50'
155
        height = '5'
155
        height = '5'
156
        if len(text) < 48:
156
        if len(text) < 48:
157
            text = ' '*int(((48-len(text))/2)) + text
157
            text = ' '*int(((48-len(text))/2)) + text
158
        else:
158
        else:
159
            width = '0'
159
            width = '0'
160
            height = '0'
160
            height = '0'
161
        if default == 'n':
161
        if default == 'n':
162
            res,data = self.calldlg('--defaultno','--yesno',text,height,width)
162
            res,data = self.calldlg('--defaultno','--yesno',text,height,width)
163
        else:
163
        else:
164
            res,data = self.calldlg('--yesno',text,height,width)
164
            res,data = self.calldlg('--yesno',text,height,width)
165
 
165
 
166
        if res == 0:
166
        if res == 0:
167
            return 'y'
167
            return 'y'
168
        return 'n'
168
        return 'n'
169
 
169
 
170
    def menu(self, text, choices, button, defopt=None):
170
    def menu(self, text, choices, button, defopt=None):
171
        text = text + ':'
171
        text = text + ':'
172
        width = '70'
172
        width = '70'
173
        height = str(8 + len(choices))
173
        height = str(8 + len(choices))
174
        args = []
174
        args = []
175
        for key,val in choices:
175
        for key,val in choices:
176
            args.append(key)
176
            args.append(key)
177
            args.append(val)
177
            args.append(val)
178
 
178
 
179
        kw = {}
179
        kw = {}
180
        if defopt:
180
        if defopt:
181
            kw['default-item'] = choices[defopt][0]
181
            kw['default-item'] = choices[defopt][0]
182
        res,data = self.calldlg('--cancel-label',button[1],
182
        res,data = self.calldlg('--cancel-label',button[1],
183
                                '--menu',text,height,width,
183
                                '--menu',text,height,width,
184
                                str(len(choices)),*args,**kw)
184
                                str(len(choices)),*args,**kw)
185
        if res == 1:
185
        if res == 1:
186
            return button[0]
186
            return button[0]
187
        elif res:
187
        elif res:
188
            print data
188
            print data
189
            raise EOFError
189
            raise EOFError
190
        return data
190
        return data
191
   
191
   
192
    def choice(self, text, choices, defopt=None):
192
    def choice(self, text, choices, defopt=None):
193
        text = text + ':'
193
        text = text + ':'
194
        width = '50'
194
        width = '50'
195
        height = str(8 + len(choices))
195
        height = str(8 + len(choices))
196
        args = []
196
        args = []
197
        for key,val in choices:
197
        for key,val in choices:
198
            args.append(key)
198
            args.append(key)
199
            args.append(val)
199
            args.append(val)
200
 
200
 
201
        kw = {}
201
        kw = {}
202
        if defopt:
202
        if defopt:
203
            kw['default-item'] = choices[defopt][0]
203
            kw['default-item'] = choices[defopt][0]
204
        res,data = self.calldlg('--nocancel','--menu',text,height,width,
204
        res,data = self.calldlg('--nocancel','--menu',text,height,width,
205
                                str(len(choices)),*args, **kw)
205
                                str(len(choices)),*args, **kw)
206
        if res:
206
        if res:
207
            print data
207
            print data
208
            raise EOFError
208
            raise EOFError
209
        return data
209
        return data
210
   
210
   
211
def read_defaults(fname,defaults):
211
def read_defaults(fname,defaults):
212
    "Read saved values from last configuration run"
212
    "Read saved values from last configuration run"
213
    f = file(fname,'r')
213
    f = file(fname,'r')
214
    for line in f:
214
    for line in f:
215
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
215
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
216
        if res:
216
        if res:
217
            defaults[res.group(1)] = res.group(2)
217
            defaults[res.group(1)] = res.group(2)
218
    f.close()
218
    f.close()
219
 
219
 
220
def check_condition(text, defaults):
220
def check_condition(text, defaults):
221
    result = True
221
    result = True
222
    conds = text.split('&')
222
    conds = text.split('&')
223
    for cond in conds:
223
    for cond in conds:
224
        if cond.startswith('(') and cond.endswith(')'):
224
        if cond.startswith('(') and cond.endswith(')'):
225
            cond = cond[1:-1]
225
            cond = cond[1:-1]
226
        if not check_dnf(cond, defaults):
226
        if not check_dnf(cond, defaults):
227
            return False
227
            return False
228
    return True
228
    return True
229
 
229
 
230
def check_dnf(text, defaults):
230
def check_dnf(text, defaults):
231
    """
231
    """
232
    Check that the condition specified on input line is True
232
    Check that the condition specified on input line is True
233
 
233
 
234
    only CNF is supported
234
    only CNF is supported
235
    """
235
    """
236
    conds = text.split('|')
236
    conds = text.split('|')
237
    for cond in conds:
237
    for cond in conds:
238
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
238
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
239
        if not res:
239
        if not res:
240
            raise RuntimeError("Invalid condition: %s" % cond)
240
            raise RuntimeError("Invalid condition: %s" % cond)
241
        condname = res.group(1)
241
        condname = res.group(1)
242
        oper = res.group(2)
242
        oper = res.group(2)
243
        condval = res.group(3)
243
        condval = res.group(3)
244
        if not defaults.has_key(condname):
244
        if not defaults.has_key(condname):
245
            raise RuntimeError("Condition var %s does not exist: %s" % \
245
            raise RuntimeError("Condition var %s does not exist: %s" % \
246
                               (condname,text))
246
                               (condname,text))
247
 
247
 
248
        if oper=='=' and  condval == defaults[condname]:
248
        if oper=='=' and  condval == defaults[condname]:
249
            return True
249
            return True
250
        if oper == '!=' and condval != defaults[condname]:
250
        if oper == '!=' and condval != defaults[condname]:
251
            return True
251
            return True
252
    return False
252
    return False
253
 
253
 
254
def parse_config(input, output, dlg, defaults={}, askonly=None):
254
def parse_config(input, output, dlg, defaults={}, askonly=None):
255
    "Parse configuration file and create Makefile.config on the fly"
255
    "Parse configuration file and create Makefile.config on the fly"
-
 
256
    def ask_the_question():
-
 
257
        "Ask question based on the type of variables to ask"
-
 
258
        # This is quite a hack, this thingy is written just to
-
 
259
        # have access to local variables..
-
 
260
        if vartype == 'y/n':
-
 
261
            return dlg.yesno(comment, default)
-
 
262
        elif vartype == 'n/y':
-
 
263
            return dlg.noyes(comment, default)
-
 
264
        elif vartype == 'choice':
-
 
265
            defopt = None
-
 
266
            if default is not None:
-
 
267
                for i,(key,val) in enumerate(choices):
-
 
268
                    if key == default:
-
 
269
                        defopt = i
-
 
270
                        break
-
 
271
            return dlg.choice(comment, choices, defopt)
-
 
272
        else:
-
 
273
            raise RuntimeError("Bad method: %s" % vartype)
-
 
274
 
-
 
275
   
256
    f = file(input, 'r')
276
    f = file(input, 'r')
257
    outf = file(output, 'w')
277
    outf = file(output, 'w')
258
 
278
 
259
    outf.write('#########################################\n')
279
    outf.write('#########################################\n')
260
    outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
280
    outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
261
    outf.write('#########################################\n\n')
281
    outf.write('#########################################\n\n')
262
 
282
 
263
    asked_names = []
283
    asked_names = []
264
 
284
 
265
    comment = ''
285
    comment = ''
266
    default = None
286
    default = None
267
    choices = []
287
    choices = []
268
    for line in f:
288
    for line in f:
269
        if line.startswith('%'):
289
        if line.startswith('%'):
270
            res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
290
            res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
271
            if not res:
291
            if not res:
272
                raise RuntimeError('Invalid command: %s' % line)
292
                raise RuntimeError('Invalid command: %s' % line)
273
            if res.group(1):
293
            if res.group(1):
274
                if not check_condition(res.group(1), defaults):
294
                if not check_condition(res.group(1), defaults):
275
                    continue
295
                    continue
276
            args = res.group(2).strip().split(' ')
296
            args = res.group(2).strip().split(' ')
277
            cmd = args[0].lower()
297
            cmd = args[0].lower()
278
            args = args[1:]
298
            args = args[1:]
279
            if cmd == 'saveas':
299
            if cmd == 'saveas':
280
                outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
300
                outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
281
               
301
               
282
            continue
302
            continue
283
           
303
           
284
        if line.startswith('!'):
304
        if line.startswith('!'):
285
            # Ask a question
305
            # Ask a question
286
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
306
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
287
            if not res:
307
            if not res:
288
                raise RuntimeError("Weird line: %s" % line)
308
                raise RuntimeError("Weird line: %s" % line)
289
            varname = res.group(2)
309
            varname = res.group(2)
290
            vartype = res.group(3)
310
            vartype = res.group(3)
291
 
311
 
292
            default = defaults.get(varname,None)
312
            default = defaults.get(varname,None)
293
           
313
           
294
            if res.group(1):
314
            if res.group(1):
295
                if not check_condition(res.group(1), defaults):
315
                if not check_condition(res.group(1), defaults):
296
                    if default is not None:
316
                    if default is not None:
297
                        outf.write('#!# %s = %s\n' % (varname, default))
317
                        outf.write('#!# %s = %s\n' % (varname, default))
298
                    # Clear cumulated values
318
                    # Clear cumulated values
299
                    comment = ''
319
                    comment = ''
300
                    default = None
320
                    default = None
301
                    choices = []
321
                    choices = []
302
                    continue
322
                    continue
303
               
323
               
304
            asked_names.append((varname,comment))
324
            asked_names.append((varname,comment))
305
 
325
 
306
            if default is not None and askonly and askonly != varname:
326
            if default is None or not askonly or askonly == varname:
307
                outf.write('%s = %s\n' % (varname, default))
327
                default = ask_the_question()
308
                continue
-
 
309
 
328
 
310
            if vartype == 'y/n':
-
 
311
                result = dlg.yesno(comment, default)
-
 
312
            elif vartype == 'n/y':
-
 
313
                result = dlg.noyes(comment, default)
-
 
314
            elif vartype == 'choice':
-
 
315
                defopt = None
-
 
316
                if default is not None:
-
 
317
                    for i,(key,val) in enumerate(choices):
-
 
318
                        if key == default:
-
 
319
                            defopt = i
-
 
320
                            break
-
 
321
                result = dlg.choice(comment, choices, defopt)
-
 
322
            else:
-
 
323
                raise RuntimeError("Bad method: %s" % vartype)
-
 
324
            outf.write('%s = %s\n' % (varname, result))
329
            outf.write('%s = %s\n' % (varname, default))
325
            # Remeber the selected value
330
            # Remeber the selected value
326
            defaults[varname] = result
331
            defaults[varname] = default
327
            # Clear cumulated values
332
            # Clear cumulated values
328
            comment = ''
333
            comment = ''
329
            default = None
334
            default = None
330
            choices = []
335
            choices = []
331
            continue
336
            continue
332
       
337
       
333
        if line.startswith('@'):
338
        if line.startswith('@'):
334
            # Add new line into the 'choice array' 
339
            # Add new line into the 'choice array' 
335
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
340
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
336
            if not res:
341
            if not res:
337
                raise RuntimeError("Bad line: %s" % line)
342
                raise RuntimeError("Bad line: %s" % line)
338
            if res.group(1):
343
            if res.group(1):
339
                if not check_condition(res.group(1),defaults):
344
                if not check_condition(res.group(1),defaults):
340
                    continue
345
                    continue
341
            choices.append((res.group(2), res.group(3)))
346
            choices.append((res.group(2), res.group(3)))
342
            continue
347
            continue
343
 
348
 
344
        # All other things print to output file
349
        # All other things print to output file
345
        outf.write(line)
350
        outf.write(line)
346
        if re.match(r'^#[^#]', line):
351
        if re.match(r'^#[^#]', line):
347
            # Last comment before question will be displayed to the user
352
            # Last comment before question will be displayed to the user
348
            comment = line[1:].strip()
353
            comment = line[1:].strip()
349
        elif line.startswith('## '):
354
        elif line.startswith('## '):
350
            # Set title of the dialog window
355
            # Set title of the dialog window
351
            dlg.set_title(line[2:].strip())
356
            dlg.set_title(line[2:].strip())
352
       
357
       
353
    outf.close()
358
    outf.close()
354
    f.close()
359
    f.close()
355
    return asked_names
360
    return asked_names
356
 
361
 
357
def main():
362
def main():
358
    defaults = {}
363
    defaults = {}
359
    try:
364
    try:
360
        dlg = Dialog()
365
        dlg = Dialog()
361
    except NotImplementedError:
366
    except NotImplementedError:
362
        dlg = NoDialog()
367
        dlg = NoDialog()
363
 
368
 
364
    if len(sys.argv) == 2 and sys.argv[1]=='default':
369
    if len(sys.argv) == 2 and sys.argv[1]=='default':
365
        defmode = True
370
        defmode = True
366
    else:
371
    else:
367
        defmode = False
372
        defmode = False
368
 
373
 
369
    # Default run will update the configuration file
374
    # Default run will update the configuration file
370
    # with newest options
375
    # with newest options
371
    if os.path.exists(OUTPUT):
376
    if os.path.exists(OUTPUT):
372
        read_defaults(OUTPUT, defaults)
377
        read_defaults(OUTPUT, defaults)
373
 
378
 
374
    # Dry run only with defaults
379
    # Dry run only with defaults
375
    varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
380
    varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
376
    # If not in default mode, present selection of all possibilities
381
    # If not in default mode, present selection of all possibilities
377
    if not defmode:
382
    if not defmode:
378
        defopt = 0
383
        defopt = 0
379
        while 1:
384
        while 1:
380
            # varnames contains variable names that were in the
385
            # varnames contains variable names that were in the
381
            # last question set
386
            # last question set
382
            choices = [ (x[1],defaults[x[0]]) for x in varnames ]
387
            choices = [ (x[1],defaults[x[0]]) for x in varnames ]
383
            res = dlg.menu('Configuration',choices,('save','Save'),defopt)
388
            res = dlg.menu('Configuration',choices,('save','Save'),defopt)
384
            if res == 'save':
389
            if res == 'save':
385
                parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
390
                parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
386
                break
391
                break
387
            # transfer description back to varname
392
            # transfer description back to varname
388
            for i,(vname,descr) in enumerate(varnames):
393
            for i,(vname,descr) in enumerate(varnames):
389
                if res == descr:
394
                if res == descr:
390
                    defopt = i
395
                    defopt = i
391
                    break
396
                    break
392
            # Ask the user a simple question, produce output
397
            # Ask the user a simple question, produce output
393
            # as if the user answered all the other questions
398
            # as if the user answered all the other questions
394
            # with default answer
399
            # with default answer
395
            varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
400
            varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
396
                                    askonly=varnames[i][0])
401
                                    askonly=varnames[i][0])
397
       
402
       
398
   
403
   
399
    if os.path.exists(OUTPUT):
404
    if os.path.exists(OUTPUT):
400
        os.unlink(OUTPUT)
405
        os.unlink(OUTPUT)
401
    os.rename(TMPOUTPUT, OUTPUT)
406
    os.rename(TMPOUTPUT, OUTPUT)
402
       
407
       
403
 
408
 
404
if __name__ == '__main__':
409
if __name__ == '__main__':
405
    main()
410
    main()
406
 
411