Subversion Repositories HelenOS

Rev

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

Rev 3937 Rev 4054
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
# Copyright (c) 2009 Martin Decky
5
# All rights reserved.
5
# All rights reserved.
6
#
6
#
7
# Redistribution and use in source and binary forms, with or without
7
# Redistribution and use in source and binary forms, with or without
8
# modification, are permitted provided that the following conditions
8
# modification, are permitted provided that the following conditions
9
# are met:
9
# are met:
10
#
10
#
11
# - Redistributions of source code must retain the above copyright
11
# - Redistributions of source code must retain the above copyright
12
#   notice, this list of conditions and the following disclaimer.
12
#   notice, this list of conditions and the following disclaimer.
13
# - Redistributions in binary form must reproduce the above copyright
13
# - Redistributions in binary form must reproduce the above copyright
14
#   notice, this list of conditions and the following disclaimer in the
14
#   notice, this list of conditions and the following disclaimer in the
15
#   documentation and/or other materials provided with the distribution.
15
#   documentation and/or other materials provided with the distribution.
16
# - The name of the author may not be used to endorse or promote products
16
# - The name of the author may not be used to endorse or promote products
17
#   derived from this software without specific prior written permission.
17
#   derived from this software without specific prior written permission.
18
#
18
#
19
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
# (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
28
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#
29
#
30
"""
30
"""
31
HelenOS configuration system
31
HelenOS configuration system
32
"""
32
"""
33
import sys
33
import sys
34
import os
34
import os
35
import re
35
import re
36
import commands
36
import commands
37
import xtui
37
import xtui
38
 
38
 
39
INPUT = sys.argv[1]
39
INPUT = sys.argv[1]
40
MAKEFILE = 'Makefile.config'
40
MAKEFILE = 'Makefile.config'
41
MACROS = 'config.h'
41
MACROS = 'config.h'
42
DEFS = 'config.defs'
42
DEFS = 'config.defs'
43
 
43
 
44
def read_defaults(fname, defaults):
44
def read_defaults(fname, defaults):
45
    "Read saved values from last configuration run"
45
    "Read saved values from last configuration run"
46
   
46
   
47
    inf = file(fname, 'r')
47
    inf = file(fname, 'r')
48
   
48
   
49
    for line in inf:
49
    for line in inf:
50
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
50
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
51
        if (res):
51
        if (res):
52
            defaults[res.group(1)] = res.group(2)
52
            defaults[res.group(1)] = res.group(2)
53
   
53
   
54
    inf.close()
54
    inf.close()
55
 
55
 
56
def check_condition(text, defaults, ask_names):
56
def check_condition(text, defaults, ask_names):
57
    "Check that the condition specified on input line is True (only CNF and DNF is supported)"
57
    "Check that the condition specified on input line is True (only CNF and DNF is supported)"
58
   
58
   
59
    ctype = 'cnf'
59
    ctype = 'cnf'
60
   
60
   
61
    if ((')|' in text) or ('|(' in text)):
61
    if ((')|' in text) or ('|(' in text)):
62
        ctype = 'dnf'
62
        ctype = 'dnf'
63
   
63
   
64
    if (ctype == 'cnf'):
64
    if (ctype == 'cnf'):
65
        conds = text.split('&')
65
        conds = text.split('&')
66
    else:
66
    else:
67
        conds = text.split('|')
67
        conds = text.split('|')
68
   
68
   
69
    for cond in conds:
69
    for cond in conds:
70
        if (cond.startswith('(')) and (cond.endswith(')')):
70
        if (cond.startswith('(')) and (cond.endswith(')')):
71
            cond = cond[1:-1]
71
            cond = cond[1:-1]
72
       
72
       
73
        inside = check_inside(cond, defaults, ctype)
73
        inside = check_inside(cond, defaults, ctype)
74
       
74
       
75
        if (ctype == 'cnf') and (not inside):
75
        if (ctype == 'cnf') and (not inside):
76
            return False
76
            return False
77
       
77
       
78
        if (ctype == 'dnf') and (inside):
78
        if (ctype == 'dnf') and (inside):
79
            return True
79
            return True
80
   
80
   
81
    if (ctype == 'cnf'):
81
    if (ctype == 'cnf'):
82
        return True
82
        return True
83
    return False
83
    return False
84
 
84
 
85
def check_inside(text, defaults, ctype):
85
def check_inside(text, defaults, ctype):
86
    "Check for condition"
86
    "Check for condition"
87
   
87
   
88
    if (ctype == 'cnf'):
88
    if (ctype == 'cnf'):
89
        conds = text.split('|')
89
        conds = text.split('|')
90
    else:
90
    else:
91
        conds = text.split('&')
91
        conds = text.split('&')
92
   
92
   
93
    for cond in conds:
93
    for cond in conds:
94
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
94
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
95
        if (not res):
95
        if (not res):
96
            raise RuntimeError("Invalid condition: %s" % cond)
96
            raise RuntimeError("Invalid condition: %s" % cond)
97
       
97
       
98
        condname = res.group(1)
98
        condname = res.group(1)
99
        oper = res.group(2)
99
        oper = res.group(2)
100
        condval = res.group(3)
100
        condval = res.group(3)
101
       
101
       
102
        if (not defaults.has_key(condname)):
102
        if (not defaults.has_key(condname)):
103
            varval = ''
103
            varval = ''
104
        else:
104
        else:
105
            varval = defaults[condname]
105
            varval = defaults[condname]
106
            if (varval == '*'):
106
            if (varval == '*'):
107
                varval = 'y'
107
                varval = 'y'
108
       
108
       
109
        if (ctype == 'cnf'):
109
        if (ctype == 'cnf'):
110
            if (oper == '=') and (condval == varval):
110
            if (oper == '=') and (condval == varval):
111
                return True
111
                return True
112
       
112
       
113
            if (oper == '!=') and (condval != varval):
113
            if (oper == '!=') and (condval != varval):
114
                return True
114
                return True
115
        else:
115
        else:
116
            if (oper == '=') and (condval != varval):
116
            if (oper == '=') and (condval != varval):
117
                return False
117
                return False
118
           
118
           
119
            if (oper == '!=') and (condval == varval):
119
            if (oper == '!=') and (condval == varval):
120
                return False
120
                return False
121
   
121
   
122
    if (ctype == 'cnf'):
122
    if (ctype == 'cnf'):
123
        return False
123
        return False
124
   
124
   
125
    return True
125
    return True
126
 
126
 
127
def parse_config(fname, ask_names):
127
def parse_config(fname, ask_names):
128
    "Parse configuration file"
128
    "Parse configuration file"
129
   
129
   
130
    inf = file(fname, 'r')
130
    inf = file(fname, 'r')
131
   
131
   
132
    name = ''
132
    name = ''
133
    choices = []
133
    choices = []
134
   
134
   
135
    for line in inf:
135
    for line in inf:
136
       
136
       
137
        if (line.startswith('!')):
137
        if (line.startswith('!')):
138
            # Ask a question
138
            # Ask a question
139
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
139
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
140
           
140
           
141
            if (not res):
141
            if (not res):
142
                raise RuntimeError("Weird line: %s" % line)
142
                raise RuntimeError("Weird line: %s" % line)
143
           
143
           
144
            cond = res.group(1)
144
            cond = res.group(1)
145
            varname = res.group(2)
145
            varname = res.group(2)
146
            vartype = res.group(3)
146
            vartype = res.group(3)
147
           
147
           
148
            ask_names.append((varname, vartype, name, choices, cond))
148
            ask_names.append((varname, vartype, name, choices, cond))
149
            name = ''
149
            name = ''
150
            choices = []
150
            choices = []
151
            continue
151
            continue
152
       
152
       
153
        if (line.startswith('@')):
153
        if (line.startswith('@')):
154
            # Add new line into the 'choices' array
154
            # Add new line into the 'choices' array
155
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
155
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
156
           
156
           
157
            if not res:
157
            if not res:
158
                raise RuntimeError("Bad line: %s" % line)
158
                raise RuntimeError("Bad line: %s" % line)
159
           
159
           
160
            choices.append((res.group(2), res.group(3)))
160
            choices.append((res.group(2), res.group(3)))
161
            continue
161
            continue
162
       
162
       
163
        if (line.startswith('%')):
163
        if (line.startswith('%')):
164
            # Name of the option
164
            # Name of the option
165
            name = line[1:].strip()
165
            name = line[1:].strip()
166
            continue
166
            continue
167
       
167
       
168
        if ((line.startswith('#')) or (line == '\n')):
168
        if ((line.startswith('#')) or (line == '\n')):
169
            # Comment or empty line
169
            # Comment or empty line
170
            continue
170
            continue
171
       
171
       
172
       
172
       
173
        raise RuntimeError("Unknown syntax: %s" % line)
173
        raise RuntimeError("Unknown syntax: %s" % line)
174
   
174
   
175
    inf.close()
175
    inf.close()
176
 
176
 
177
def yes_no(default):
177
def yes_no(default):
178
    "Return '*' if yes, ' ' if no"
178
    "Return '*' if yes, ' ' if no"
179
   
179
   
180
    if (default == 'y'):
180
    if (default == 'y'):
181
        return '*'
181
        return '*'
182
   
182
   
183
    return ' '
183
    return ' '
184
 
184
 
185
def subchoice(screen, name, choices, default):
185
def subchoice(screen, name, choices, default):
186
    "Return choice of choices"
186
    "Return choice of choices"
187
   
187
   
188
    maxkey = 0
188
    maxkey = 0
189
    for key, val in choices:
189
    for key, val in choices:
190
        length = len(key)
190
        length = len(key)
191
        if (length > maxkey):
191
        if (length > maxkey):
192
            maxkey = length
192
            maxkey = length
193
   
193
   
194
    options = []
194
    options = []
195
    position = None
195
    position = None
196
    cnt = 0
196
    cnt = 0
197
    for key, val in choices:
197
    for key, val in choices:
198
        if ((default) and (key == default)):
198
        if ((default) and (key == default)):
199
            position = cnt
199
            position = cnt
200
       
200
       
201
        options.append(" %-*s  %s " % (maxkey, key, val))
201
        options.append(" %-*s  %s " % (maxkey, key, val))
202
        cnt += 1
202
        cnt += 1
203
   
203
   
204
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
204
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
205
   
205
   
206
    if (button == 'cancel'):
206
    if (button == 'cancel'):
207
        return None
207
        return None
208
   
208
   
209
    return choices[value][0]
209
    return choices[value][0]
210
 
210
 
211
def check_choices(defaults, ask_names):
211
def check_choices(defaults, ask_names):
212
    "Check whether all accessible variables have a default"
212
    "Check whether all accessible variables have a default"
213
   
213
   
214
    for varname, vartype, name, choices, cond in ask_names:
214
    for varname, vartype, name, choices, cond in ask_names:
215
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
215
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
216
            continue
216
            continue
217
       
217
       
218
        if (not defaults.has_key(varname)):
218
        if (not defaults.has_key(varname)):
219
            return False
219
            return False
220
   
220
   
221
    return True
221
    return True
222
 
222
 
223
def create_output(mkname, mcname, dfname, defaults, ask_names):
223
def create_output(mkname, mcname, dfname, defaults, ask_names):
224
    "Create output configuration"
224
    "Create output configuration"
225
   
225
   
226
    revision = commands.getoutput('svnversion . 2> /dev/null')
226
    revision = commands.getoutput('svnversion . 2> /dev/null')
227
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
227
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
228
   
228
   
229
    outmk = file(mkname, 'w')
229
    outmk = file(mkname, 'w')
230
    outmc = file(mcname, 'w')
230
    outmc = file(mcname, 'w')
231
    outdf = file(dfname, 'w')
231
    outdf = file(dfname, 'w')
232
   
232
   
233
    outmk.write('#########################################\n')
233
    outmk.write('#########################################\n')
234
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
234
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
235
    outmk.write('#########################################\n\n')
235
    outmk.write('#########################################\n\n')
236
   
236
   
237
    outmc.write('/***************************************\n')
237
    outmc.write('/***************************************\n')
238
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
238
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
239
    outmc.write(' ***************************************/\n\n')
239
    outmc.write(' ***************************************/\n\n')
240
   
240
   
241
    outdf.write('#########################################\n')
241
    outdf.write('#########################################\n')
242
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
242
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
243
    outdf.write('#########################################\n\n')
243
    outdf.write('#########################################\n\n')
244
    outdf.write('CONFIG_DEFS =')
244
    outdf.write('CONFIG_DEFS =')
245
   
245
   
246
    for varname, vartype, name, choices, cond in ask_names:
246
    for varname, vartype, name, choices, cond in ask_names:
247
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
247
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
248
            continue
248
            continue
249
       
249
       
250
        if (not defaults.has_key(varname)):
250
        if (not defaults.has_key(varname)):
251
            default = ''
251
            default = ''
252
        else:
252
        else:
253
            default = defaults[varname]
253
            default = defaults[varname]
254
            if (default == '*'):
254
            if (default == '*'):
255
                default = 'y'
255
                default = 'y'
256
       
256
       
257
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
257
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
258
       
258
       
259
        if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")):
259
        if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")):
260
            if (default == "y"):
260
            if (default == "y"):
261
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
261
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
262
                outdf.write(' -D%s' % varname)
262
                outdf.write(' -D%s' % varname)
263
        else:
263
        else:
264
            outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
264
            outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
265
            outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
265
            outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
266
   
266
   
267
    outmk.write('REVISION = %s\n' % revision)
267
    outmk.write('REVISION = %s\n' % revision)
268
    outmk.write('TIMESTAMP = %s\n' % timestamp)
268
    outmk.write('TIMESTAMP = %s\n' % timestamp)
269
   
269
   
270
    outmc.write('#define REVISION %s\n' % revision)
270
    outmc.write('#define REVISION %s\n' % revision)
271
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
271
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
272
   
272
   
273
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
273
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
274
   
274
   
275
    outmk.close()
275
    outmk.close()
276
    outmc.close()
276
    outmc.close()
277
    outdf.close()
277
    outdf.close()
278
 
278
 
279
def main():
279
def main():
280
    defaults = {}
280
    defaults = {}
281
    ask_names = []
281
    ask_names = []
282
   
282
   
283
    # Parse configuration file
283
    # Parse configuration file
284
    parse_config(INPUT, ask_names)
284
    parse_config(INPUT, ask_names)
285
   
285
   
286
    # Read defaults from previous run
286
    # Read defaults from previous run
287
    if os.path.exists(MAKEFILE):
287
    if os.path.exists(MAKEFILE):
288
        read_defaults(MAKEFILE, defaults)
288
        read_defaults(MAKEFILE, defaults)
289
   
289
   
290
    # Default mode: only check defaults and regenerate configuration
290
    # Default mode: only check defaults and regenerate configuration
291
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
291
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
292
        if (check_choices(defaults, ask_names)):
292
        if (check_choices(defaults, ask_names)):
293
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
293
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
294
            return 0
294
            return 0
295
   
295
   
296
    # Check mode: only check defaults
296
    # Check mode: only check defaults
297
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
297
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
298
        if (check_choices(defaults, ask_names)):
298
        if (check_choices(defaults, ask_names)):
299
            return 0
299
            return 0
300
        return 1
300
        return 1
301
   
301
   
302
    screen = xtui.screen_init()
302
    screen = xtui.screen_init()
303
    try:
303
    try:
304
        selname = None
304
        selname = None
305
        while True:
305
        while True:
306
           
306
           
307
            # Cancel out all defaults which have to be deduced
307
            # Cancel out all defaults which have to be deduced
308
            for varname, vartype, name, choices, cond in ask_names:
308
            for varname, vartype, name, choices, cond in ask_names:
309
                if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
309
                if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
310
                    defaults[varname] = None
310
                    defaults[varname] = None
311
           
311
           
312
            options = []
312
            options = []
313
            opt2row = {}
313
            opt2row = {}
314
            position = None
314
            position = None
315
            cnt = 0
315
            cnt = 0
316
            for varname, vartype, name, choices, cond in ask_names:
316
            for varname, vartype, name, choices, cond in ask_names:
317
               
317
               
318
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
318
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
319
                    continue
319
                    continue
320
               
320
               
321
                if (varname == selname):
321
                if (varname == selname):
322
                    position = cnt
322
                    position = cnt
323
               
323
               
324
                if (not defaults.has_key(varname)):
324
                if (not defaults.has_key(varname)):
325
                    default = None
325
                    default = None
326
                else:
326
                else:
327
                    default = defaults[varname]
327
                    default = defaults[varname]
328
               
328
               
329
                if (vartype == 'choice'):
329
                if (vartype == 'choice'):
330
                    # Check if the default is an acceptable value
330
                    # Check if the default is an acceptable value
331
                    if ((default) and (not default in [choice[0] for choice in choices])):
331
                    if ((default) and (not default in [choice[0] for choice in choices])):
332
                        default = None
332
                        default = None
333
                        defaults.pop(varname)
333
                        defaults.pop(varname)
334
                   
334
                   
335
                    # If there is just one option, use it
335
                    # If there is just one option, use it
336
                    if (len(choices) == 1):
336
                    if (len(choices) == 1):
337
                        defaults[varname] = choices[0][0]
337
                        defaults[varname] = choices[0][0]
338
                        continue
338
                        continue
339
                   
339
                   
-
 
340
                    if (default == None):
-
 
341
                        options.append("?     %s --> " % name)
-
 
342
                    else:
340
                    options.append("     %s [%s] --> " % (name, default))
343
                        options.append("      %s [%s] --> " % (name, default))
341
                elif (vartype == 'y'):
344
                elif (vartype == 'y'):
342
                    defaults[varname] = '*'
345
                    defaults[varname] = '*'
343
                    continue
346
                    continue
344
                elif (vartype == 'y/n'):
347
                elif (vartype == 'y/n'):
345
                    if (default == None):
348
                    if (default == None):
346
                        default = 'y'
349
                        default = 'y'
347
                        defaults[varname] = default
350
                        defaults[varname] = default
348
                    options.append(" <%s> %s " % (yes_no(default), name))
351
                    options.append("  <%s> %s " % (yes_no(default), name))
349
                elif (vartype == 'n/y'):
352
                elif (vartype == 'n/y'):
350
                    if (default == None):
353
                    if (default == None):
351
                        default = 'n'
354
                        default = 'n'
352
                        defaults[varname] = default
355
                        defaults[varname] = default
353
                    options.append(" <%s> %s " % (yes_no(default), name))
356
                    options.append("  <%s> %s " % (yes_no(default), name))
354
                else:
357
                else:
355
                    raise RuntimeError("Unknown variable type: %s" % vartype)
358
                    raise RuntimeError("Unknown variable type: %s" % vartype)
356
               
359
               
357
                opt2row[cnt] = (varname, vartype, name, choices)
360
                opt2row[cnt] = (varname, vartype, name, choices)
358
               
361
               
359
                cnt += 1
362
                cnt += 1
360
           
363
           
361
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
364
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
362
           
365
           
363
            if (button == 'cancel'):
366
            if (button == 'cancel'):
364
                return 'Configuration canceled'
367
                return 'Configuration canceled'
365
           
368
           
366
            if (not opt2row.has_key(value)):
369
            if (not opt2row.has_key(value)):
367
                raise RuntimeError("Error selecting value: %s" % value)
370
                raise RuntimeError("Error selecting value: %s" % value)
368
           
371
           
369
            (selname, seltype, name, choices) = opt2row[value]
372
            (selname, seltype, name, choices) = opt2row[value]
370
           
373
           
371
            if (not defaults.has_key(selname)):
374
            if (not defaults.has_key(selname)):
372
                    default = None
375
                    default = None
373
            else:
376
            else:
374
                default = defaults[selname]
377
                default = defaults[selname]
375
           
378
           
376
            if (button == 'done'):
379
            if (button == 'done'):
377
                if (check_choices(defaults, ask_names)):
380
                if (check_choices(defaults, ask_names)):
378
                    break
381
                    break
379
                else:
382
                else:
380
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values.')
383
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values. These options are marked with the "?" sign.')
381
                    continue
384
                    continue
382
           
385
           
383
            if (seltype == 'choice'):
386
            if (seltype == 'choice'):
384
                defaults[selname] = subchoice(screen, name, choices, default)
387
                defaults[selname] = subchoice(screen, name, choices, default)
385
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
388
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
386
                if (defaults[selname] == 'y'):
389
                if (defaults[selname] == 'y'):
387
                    defaults[selname] = 'n'
390
                    defaults[selname] = 'n'
388
                else:
391
                else:
389
                    defaults[selname] = 'y'
392
                    defaults[selname] = 'y'
390
    finally:
393
    finally:
391
        xtui.screen_done(screen)
394
        xtui.screen_done(screen)
392
   
395
   
393
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
396
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
394
    return 0
397
    return 0
395
 
398
 
396
if __name__ == '__main__':
399
if __name__ == '__main__':
397
    sys.exit(main())
400
    sys.exit(main())
398
 
401