Subversion Repositories HelenOS

Rev

Rev 3107 | Rev 4341 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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