Subversion Repositories HelenOS-historic

Rev

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

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