Subversion Repositories HelenOS-historic

Rev

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

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