Subversion Repositories HelenOS-historic

Rev

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

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