Subversion Repositories HelenOS

Rev

Rev 4344 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4344 Rev 4346
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
PRECONF = 'defaults'
43
 
44
 
44
def read_defaults(fname, defaults):
45
def read_defaults(fname, defaults):
45
    "Read saved values from last configuration run"
46
    "Read saved values from last configuration run"
46
   
47
   
47
    inf = file(fname, 'r')
48
    inf = file(fname, 'r')
48
   
49
   
49
    for line in inf:
50
    for line in inf:
50
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
51
        res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
51
        if (res):
52
        if (res):
52
            defaults[res.group(1)] = res.group(2)
53
            defaults[res.group(1)] = res.group(2)
53
   
54
   
54
    inf.close()
55
    inf.close()
55
 
56
 
56
def check_condition(text, defaults, ask_names):
57
def check_condition(text, defaults, ask_names):
57
    "Check that the condition specified on input line is True (only CNF and DNF is supported)"
58
    "Check that the condition specified on input line is True (only CNF and DNF is supported)"
58
   
59
   
59
    ctype = 'cnf'
60
    ctype = 'cnf'
60
   
61
   
61
    if ((')|' in text) or ('|(' in text)):
62
    if ((')|' in text) or ('|(' in text)):
62
        ctype = 'dnf'
63
        ctype = 'dnf'
63
   
64
   
64
    if (ctype == 'cnf'):
65
    if (ctype == 'cnf'):
65
        conds = text.split('&')
66
        conds = text.split('&')
66
    else:
67
    else:
67
        conds = text.split('|')
68
        conds = text.split('|')
68
   
69
   
69
    for cond in conds:
70
    for cond in conds:
70
        if (cond.startswith('(')) and (cond.endswith(')')):
71
        if (cond.startswith('(')) and (cond.endswith(')')):
71
            cond = cond[1:-1]
72
            cond = cond[1:-1]
72
       
73
       
73
        inside = check_inside(cond, defaults, ctype)
74
        inside = check_inside(cond, defaults, ctype)
74
       
75
       
75
        if (ctype == 'cnf') and (not inside):
76
        if (ctype == 'cnf') and (not inside):
76
            return False
77
            return False
77
       
78
       
78
        if (ctype == 'dnf') and (inside):
79
        if (ctype == 'dnf') and (inside):
79
            return True
80
            return True
80
   
81
   
81
    if (ctype == 'cnf'):
82
    if (ctype == 'cnf'):
82
        return True
83
        return True
83
    return False
84
    return False
84
 
85
 
85
def check_inside(text, defaults, ctype):
86
def check_inside(text, defaults, ctype):
86
    "Check for condition"
87
    "Check for condition"
87
   
88
   
88
    if (ctype == 'cnf'):
89
    if (ctype == 'cnf'):
89
        conds = text.split('|')
90
        conds = text.split('|')
90
    else:
91
    else:
91
        conds = text.split('&')
92
        conds = text.split('&')
92
   
93
   
93
    for cond in conds:
94
    for cond in conds:
94
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
95
        res = re.match(r'^(.*?)(!?=)(.*)$', cond)
95
        if (not res):
96
        if (not res):
96
            raise RuntimeError("Invalid condition: %s" % cond)
97
            raise RuntimeError("Invalid condition: %s" % cond)
97
       
98
       
98
        condname = res.group(1)
99
        condname = res.group(1)
99
        oper = res.group(2)
100
        oper = res.group(2)
100
        condval = res.group(3)
101
        condval = res.group(3)
101
       
102
       
102
        if (not defaults.has_key(condname)):
103
        if (not defaults.has_key(condname)):
103
            varval = ''
104
            varval = ''
104
        else:
105
        else:
105
            varval = defaults[condname]
106
            varval = defaults[condname]
106
            if (varval == '*'):
107
            if (varval == '*'):
107
                varval = 'y'
108
                varval = 'y'
108
       
109
       
109
        if (ctype == 'cnf'):
110
        if (ctype == 'cnf'):
110
            if (oper == '=') and (condval == varval):
111
            if (oper == '=') and (condval == varval):
111
                return True
112
                return True
112
       
113
       
113
            if (oper == '!=') and (condval != varval):
114
            if (oper == '!=') and (condval != varval):
114
                return True
115
                return True
115
        else:
116
        else:
116
            if (oper == '=') and (condval != varval):
117
            if (oper == '=') and (condval != varval):
117
                return False
118
                return False
118
           
119
           
119
            if (oper == '!=') and (condval == varval):
120
            if (oper == '!=') and (condval == varval):
120
                return False
121
                return False
121
   
122
   
122
    if (ctype == 'cnf'):
123
    if (ctype == 'cnf'):
123
        return False
124
        return False
124
   
125
   
125
    return True
126
    return True
126
 
127
 
127
def parse_config(fname, ask_names):
128
def parse_config(fname, ask_names):
128
    "Parse configuration file"
129
    "Parse configuration file"
129
   
130
   
130
    inf = file(fname, 'r')
131
    inf = file(fname, 'r')
131
   
132
   
132
    name = ''
133
    name = ''
133
    choices = []
134
    choices = []
134
   
135
   
135
    for line in inf:
136
    for line in inf:
136
       
137
       
137
        if (line.startswith('!')):
138
        if (line.startswith('!')):
138
            # Ask a question
139
            # Ask a question
139
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
140
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
140
           
141
           
141
            if (not res):
142
            if (not res):
142
                raise RuntimeError("Weird line: %s" % line)
143
                raise RuntimeError("Weird line: %s" % line)
143
           
144
           
144
            cond = res.group(1)
145
            cond = res.group(1)
145
            varname = res.group(2)
146
            varname = res.group(2)
146
            vartype = res.group(3)
147
            vartype = res.group(3)
147
           
148
           
148
            ask_names.append((varname, vartype, name, choices, cond))
149
            ask_names.append((varname, vartype, name, choices, cond))
149
            name = ''
150
            name = ''
150
            choices = []
151
            choices = []
151
            continue
152
            continue
152
       
153
       
153
        if (line.startswith('@')):
154
        if (line.startswith('@')):
154
            # Add new line into the 'choices' array
155
            # Add new line into the 'choices' array
155
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
156
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
156
           
157
           
157
            if not res:
158
            if not res:
158
                raise RuntimeError("Bad line: %s" % line)
159
                raise RuntimeError("Bad line: %s" % line)
159
           
160
           
160
            choices.append((res.group(2), res.group(3)))
161
            choices.append((res.group(2), res.group(3)))
161
            continue
162
            continue
162
       
163
       
163
        if (line.startswith('%')):
164
        if (line.startswith('%')):
164
            # Name of the option
165
            # Name of the option
165
            name = line[1:].strip()
166
            name = line[1:].strip()
166
            continue
167
            continue
167
       
168
       
168
        if ((line.startswith('#')) or (line == '\n')):
169
        if ((line.startswith('#')) or (line == '\n')):
169
            # Comment or empty line
170
            # Comment or empty line
170
            continue
171
            continue
171
       
172
       
172
       
173
       
173
        raise RuntimeError("Unknown syntax: %s" % line)
174
        raise RuntimeError("Unknown syntax: %s" % line)
174
   
175
   
175
    inf.close()
176
    inf.close()
176
 
177
 
177
def yes_no(default):
178
def yes_no(default):
178
    "Return '*' if yes, ' ' if no"
179
    "Return '*' if yes, ' ' if no"
179
   
180
   
180
    if (default == 'y'):
181
    if (default == 'y'):
181
        return '*'
182
        return '*'
182
   
183
   
183
    return ' '
184
    return ' '
184
 
185
 
185
def subchoice(screen, name, choices, default):
186
def subchoice(screen, name, choices, default):
186
    "Return choice of choices"
187
    "Return choice of choices"
187
   
188
   
188
    maxkey = 0
189
    maxkey = 0
189
    for key, val in choices:
190
    for key, val in choices:
190
        length = len(key)
191
        length = len(key)
191
        if (length > maxkey):
192
        if (length > maxkey):
192
            maxkey = length
193
            maxkey = length
193
   
194
   
194
    options = []
195
    options = []
195
    position = None
196
    position = None
196
    cnt = 0
197
    cnt = 0
197
    for key, val in choices:
198
    for key, val in choices:
198
        if ((default) and (key == default)):
199
        if ((default) and (key == default)):
199
            position = cnt
200
            position = cnt
200
       
201
       
201
        options.append(" %-*s  %s " % (maxkey, key, val))
202
        options.append(" %-*s  %s " % (maxkey, key, val))
202
        cnt += 1
203
        cnt += 1
203
   
204
   
204
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
205
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
205
   
206
   
206
    if (button == 'cancel'):
207
    if (button == 'cancel'):
207
        return None
208
        return None
208
   
209
   
209
    return choices[value][0]
210
    return choices[value][0]
210
 
211
 
211
def check_choices(defaults, ask_names):
212
def check_choices(defaults, ask_names):
212
    "Check whether all accessible variables have a default"
213
    "Check whether all accessible variables have a default"
213
   
214
   
214
    for varname, vartype, name, choices, cond in ask_names:
215
    for varname, vartype, name, choices, cond in ask_names:
215
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
216
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
216
            continue
217
            continue
217
       
218
       
218
        if (not defaults.has_key(varname)):
219
        if (not defaults.has_key(varname)):
219
            return False
220
            return False
220
   
221
   
221
    return True
222
    return True
222
 
223
 
223
def create_output(mkname, mcname, dfname, defaults, ask_names):
224
def create_output(mkname, mcname, dfname, defaults, ask_names):
224
    "Create output configuration"
225
    "Create output configuration"
225
   
226
   
226
    revision = commands.getoutput('svnversion . 2> /dev/null')
227
    revision = commands.getoutput('svnversion . 2> /dev/null')
227
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
228
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
228
   
229
   
229
    outmk = file(mkname, 'w')
230
    outmk = file(mkname, 'w')
230
    outmc = file(mcname, 'w')
231
    outmc = file(mcname, 'w')
231
    outdf = file(dfname, 'w')
232
    outdf = file(dfname, 'w')
232
   
233
   
233
    outmk.write('#########################################\n')
234
    outmk.write('#########################################\n')
234
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
235
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
235
    outmk.write('#########################################\n\n')
236
    outmk.write('#########################################\n\n')
236
   
237
   
237
    outmc.write('/***************************************\n')
238
    outmc.write('/***************************************\n')
238
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
239
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
239
    outmc.write(' ***************************************/\n\n')
240
    outmc.write(' ***************************************/\n\n')
240
   
241
   
241
    outdf.write('#########################################\n')
242
    outdf.write('#########################################\n')
242
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
243
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
243
    outdf.write('#########################################\n\n')
244
    outdf.write('#########################################\n\n')
244
    outdf.write('CONFIG_DEFS =')
245
    outdf.write('CONFIG_DEFS =')
245
   
246
   
246
    for varname, vartype, name, choices, cond in ask_names:
247
    for varname, vartype, name, choices, cond in ask_names:
247
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
248
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
248
            continue
249
            continue
249
       
250
       
250
        if (not defaults.has_key(varname)):
251
        if (not defaults.has_key(varname)):
251
            default = ''
252
            default = ''
252
        else:
253
        else:
253
            default = defaults[varname]
254
            default = defaults[varname]
254
            if (default == '*'):
255
            if (default == '*'):
255
                default = 'y'
256
                default = 'y'
256
       
257
       
257
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
258
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
258
       
259
       
259
        if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")):
260
        if ((vartype == "y") or (vartype == "n") or (vartype == "y/n") or (vartype == "n/y")):
260
            if (default == "y"):
261
            if (default == "y"):
261
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
262
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
262
                outdf.write(' -D%s' % varname)
263
                outdf.write(' -D%s' % varname)
263
        else:
264
        else:
264
            outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
265
            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))
266
            outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
266
   
267
   
267
    outmk.write('REVISION = %s\n' % revision)
268
    outmk.write('REVISION = %s\n' % revision)
268
    outmk.write('TIMESTAMP = %s\n' % timestamp)
269
    outmk.write('TIMESTAMP = %s\n' % timestamp)
269
   
270
   
270
    outmc.write('#define REVISION %s\n' % revision)
271
    outmc.write('#define REVISION %s\n' % revision)
271
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
272
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
272
   
273
   
273
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
274
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
274
   
275
   
275
    outmk.close()
276
    outmk.close()
276
    outmc.close()
277
    outmc.close()
277
    outdf.close()
278
    outdf.close()
278
 
279
 
-
 
280
def sorted_dir(root):
-
 
281
    list = os.listdir(root)
-
 
282
    list.sort()
-
 
283
    return list
-
 
284
 
-
 
285
def read_preconfigured(root, fname, screen, defaults):
-
 
286
    options = []
-
 
287
    opt2path = {}
-
 
288
    cnt = 0
-
 
289
   
-
 
290
    # Look for profiles
-
 
291
    for name in sorted_dir(root):
-
 
292
        path = os.path.join(root, name)
-
 
293
        canon = os.path.join(path, fname)
-
 
294
       
-
 
295
        if ((os.path.isdir(path)) and (os.path.exists(canon)) and (os.path.isfile(canon))):
-
 
296
            subprofile = False
-
 
297
           
-
 
298
            # Look for subprofiles
-
 
299
            for subname in sorted_dir(path):
-
 
300
                subpath = os.path.join(path, subname)
-
 
301
                subcanon = os.path.join(subpath, fname)
-
 
302
               
-
 
303
                if ((os.path.isdir(subpath)) and (os.path.exists(subcanon)) and (os.path.isfile(subcanon))):
-
 
304
                    subprofile = True
-
 
305
                    options.append("%s (%s)" % (name, subname))
-
 
306
                    opt2path[cnt] = (canon, subcanon)
-
 
307
                    cnt += 1
-
 
308
           
-
 
309
            if (not subprofile):
-
 
310
                options.append(name)
-
 
311
                opt2path[cnt] = (canon, None)
-
 
312
                cnt += 1
-
 
313
   
-
 
314
    (button, value) = xtui.choice_window(screen, 'Load preconfigured defaults', 'Choose configuration profile', options, None)
-
 
315
   
-
 
316
    if (button == 'cancel'):
-
 
317
        return None
-
 
318
   
-
 
319
    read_defaults(opt2path[value][0], defaults)
-
 
320
    if (opt2path[value][1] != None):
-
 
321
        read_defaults(opt2path[value][1], defaults)
-
 
322
 
279
def main():
323
def main():
280
    defaults = {}
324
    defaults = {}
281
    ask_names = []
325
    ask_names = []
282
   
326
   
283
    # Parse configuration file
327
    # Parse configuration file
284
    parse_config(INPUT, ask_names)
328
    parse_config(INPUT, ask_names)
285
   
329
   
286
    # Read defaults from previous run
330
    # Read defaults from previous run
287
    if os.path.exists(MAKEFILE):
331
    if os.path.exists(MAKEFILE):
288
        read_defaults(MAKEFILE, defaults)
332
        read_defaults(MAKEFILE, defaults)
289
   
333
   
290
    # Default mode: only check defaults and regenerate configuration
334
    # Default mode: only check defaults and regenerate configuration
291
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
335
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
292
        if (check_choices(defaults, ask_names)):
336
        if (check_choices(defaults, ask_names)):
293
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
337
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
294
            return 0
338
            return 0
295
   
339
   
296
    # Check mode: only check defaults
340
    # Check mode: only check defaults
297
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
341
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
298
        if (check_choices(defaults, ask_names)):
342
        if (check_choices(defaults, ask_names)):
299
            return 0
343
            return 0
300
        return 1
344
        return 1
301
   
345
   
302
    screen = xtui.screen_init()
346
    screen = xtui.screen_init()
303
    try:
347
    try:
304
        selname = None
348
        selname = None
-
 
349
        position = None
305
        while True:
350
        while True:
306
           
351
           
307
            # Cancel out all defaults which have to be deduced
352
            # Cancel out all defaults which have to be deduced
308
            for varname, vartype, name, choices, cond in ask_names:
353
            for varname, vartype, name, choices, cond in ask_names:
309
                if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
354
                if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
310
                    defaults[varname] = None
355
                    defaults[varname] = None
311
           
356
           
312
            options = []
357
            options = []
313
            opt2row = {}
358
            opt2row = {}
314
            position = None
359
            cnt = 1
315
            cnt = 0
360
           
-
 
361
            options.append("  --- Load preconfigured defaults ... ")
-
 
362
           
316
            for varname, vartype, name, choices, cond in ask_names:
363
            for varname, vartype, name, choices, cond in ask_names:
317
               
364
               
318
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
365
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
319
                    continue
366
                    continue
320
               
367
               
321
                if (varname == selname):
368
                if (varname == selname):
322
                    position = cnt
369
                    position = cnt
323
               
370
               
324
                if (not defaults.has_key(varname)):
371
                if (not defaults.has_key(varname)):
325
                    default = None
372
                    default = None
326
                else:
373
                else:
327
                    default = defaults[varname]
374
                    default = defaults[varname]
328
               
375
               
329
                if (vartype == 'choice'):
376
                if (vartype == 'choice'):
330
                    # Check if the default is an acceptable value
377
                    # Check if the default is an acceptable value
331
                    if ((default) and (not default in [choice[0] for choice in choices])):
378
                    if ((default) and (not default in [choice[0] for choice in choices])):
332
                        default = None
379
                        default = None
333
                        defaults.pop(varname)
380
                        defaults.pop(varname)
334
                   
381
                   
335
                    # If there is just one option, use it
382
                    # If there is just one option, use it
336
                    if (len(choices) == 1):
383
                    if (len(choices) == 1):
337
                        defaults[varname] = choices[0][0]
384
                        defaults[varname] = choices[0][0]
338
                        continue
385
                        continue
339
                   
386
                   
-
 
387
                    if (default == None):
-
 
388
                        options.append("?     %s --> " % name)
-
 
389
                    else:
340
                    options.append("     %s [%s] --> " % (name, default))
390
                        options.append("      %s [%s] --> " % (name, default))
341
                elif (vartype == 'y'):
391
                elif (vartype == 'y'):
342
                    defaults[varname] = '*'
392
                    defaults[varname] = '*'
343
                    continue
393
                    continue
-
 
394
                elif (vartype == 'n'):
-
 
395
                    defaults[varname] = 'n'
-
 
396
                    continue
344
                elif (vartype == 'y/n'):
397
                elif (vartype == 'y/n'):
345
                    if (default == None):
398
                    if (default == None):
346
                        default = 'y'
399
                        default = 'y'
347
                        defaults[varname] = default
400
                        defaults[varname] = default
348
                    options.append(" <%s> %s " % (yes_no(default), name))
401
                    options.append("  <%s> %s " % (yes_no(default), name))
349
                elif (vartype == 'n/y'):
402
                elif (vartype == 'n/y'):
350
                    if (default == None):
403
                    if (default == None):
351
                        default = 'n'
404
                        default = 'n'
352
                        defaults[varname] = default
405
                        defaults[varname] = default
353
                    options.append(" <%s> %s " % (yes_no(default), name))
406
                    options.append("  <%s> %s " % (yes_no(default), name))
354
                else:
407
                else:
355
                    raise RuntimeError("Unknown variable type: %s" % vartype)
408
                    raise RuntimeError("Unknown variable type: %s" % vartype)
356
               
409
               
357
                opt2row[cnt] = (varname, vartype, name, choices)
410
                opt2row[cnt] = (varname, vartype, name, choices)
358
               
411
               
359
                cnt += 1
412
                cnt += 1
360
           
413
           
-
 
414
            if (position >= options):
-
 
415
                position = None
-
 
416
           
361
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
417
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
362
           
418
           
363
            if (button == 'cancel'):
419
            if (button == 'cancel'):
364
                return 'Configuration canceled'
420
                return 'Configuration canceled'
365
           
421
           
-
 
422
            if (button == 'done'):
-
 
423
                if (check_choices(defaults, ask_names)):
-
 
424
                    break
-
 
425
                else:
-
 
426
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values. These options are marked with the "?" sign.')
-
 
427
                    continue
-
 
428
           
-
 
429
            if (value == 0):
-
 
430
                read_preconfigured(PRECONF, MAKEFILE, screen, defaults)
-
 
431
                position = 1
-
 
432
                continue
-
 
433
           
-
 
434
            position = None
366
            if (not opt2row.has_key(value)):
435
            if (not opt2row.has_key(value)):
367
                raise RuntimeError("Error selecting value: %s" % value)
436
                raise RuntimeError("Error selecting value: %s" % value)
368
           
437
           
369
            (selname, seltype, name, choices) = opt2row[value]
438
            (selname, seltype, name, choices) = opt2row[value]
370
           
439
           
371
            if (not defaults.has_key(selname)):
440
            if (not defaults.has_key(selname)):
372
                    default = None
441
                    default = None
373
            else:
442
            else:
374
                default = defaults[selname]
443
                default = defaults[selname]
375
           
444
           
376
            if (button == 'done'):
-
 
377
                if (check_choices(defaults, ask_names)):
-
 
378
                    break
-
 
379
                else:
-
 
380
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values.')
-
 
381
                    continue
-
 
382
           
-
 
383
            if (seltype == 'choice'):
445
            if (seltype == 'choice'):
384
                defaults[selname] = subchoice(screen, name, choices, default)
446
                defaults[selname] = subchoice(screen, name, choices, default)
385
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
447
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
386
                if (defaults[selname] == 'y'):
448
                if (defaults[selname] == 'y'):
387
                    defaults[selname] = 'n'
449
                    defaults[selname] = 'n'
388
                else:
450
                else:
389
                    defaults[selname] = 'y'
451
                    defaults[selname] = 'y'
390
    finally:
452
    finally:
391
        xtui.screen_done(screen)
453
        xtui.screen_done(screen)
392
   
454
   
393
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
455
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
394
    return 0
456
    return 0
395
 
457
 
396
if __name__ == '__main__':
458
if __name__ == '__main__':
397
    sys.exit(main())
459
    sys.exit(main())
398
 
460