Subversion Repositories HelenOS

Rev

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

Rev 3881 Rev 3909
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 for condition"
57
    "Check for condition"
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 that the condition specified on input line is True (only CNF is supported)"
86
    "Check that the condition specified on input line is True (only CNF is supported)"
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
       
106
       
107
        if (ctype == 'cnf'):
107
        if (ctype == 'cnf'):
108
            if (oper == '=') and (condval == varval):
108
            if (oper == '=') and (condval == varval):
109
                return True
109
                return True
110
       
110
       
111
            if (oper == '!=') and (condval != varval):
111
            if (oper == '!=') and (condval != varval):
112
                return True
112
                return True
113
        else:
113
        else:
114
            if (oper == '=') and (condval != varval):
114
            if (oper == '=') and (condval != varval):
115
                return False
115
                return False
116
           
116
           
117
            if (oper == '!=') and (condval == varval):
117
            if (oper == '!=') and (condval == varval):
118
                return False
118
                return False
119
   
119
   
120
    if (ctype == 'cnf'):
120
    if (ctype == 'cnf'):
121
        return False
121
        return False
122
   
122
   
123
    return True
123
    return True
124
 
124
 
125
def parse_config(fname, ask_names):
125
def parse_config(fname, ask_names):
126
    "Parse configuration file"
126
    "Parse configuration file"
127
   
127
   
128
    inf = file(fname, 'r')
128
    inf = file(fname, 'r')
129
   
129
   
130
    name = ''
130
    name = ''
131
    choices = []
131
    choices = []
132
   
132
   
133
    for line in inf:
133
    for line in inf:
134
       
134
       
135
        if (line.startswith('!')):
135
        if (line.startswith('!')):
136
            # Ask a question
136
            # Ask a question
137
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
137
            res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
138
           
138
           
139
            if (not res):
139
            if (not res):
140
                raise RuntimeError("Weird line: %s" % line)
140
                raise RuntimeError("Weird line: %s" % line)
141
           
141
           
142
            cond = res.group(1)
142
            cond = res.group(1)
143
            varname = res.group(2)
143
            varname = res.group(2)
144
            vartype = res.group(3)
144
            vartype = res.group(3)
145
           
145
           
146
            ask_names.append((varname, vartype, name, choices, cond))
146
            ask_names.append((varname, vartype, name, choices, cond))
147
            name = ''
147
            name = ''
148
            choices = []
148
            choices = []
149
            continue
149
            continue
150
       
150
       
151
        if (line.startswith('@')):
151
        if (line.startswith('@')):
152
            # Add new line into the 'choices' array
152
            # Add new line into the 'choices' array
153
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
153
            res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
154
           
154
           
155
            if not res:
155
            if not res:
156
                raise RuntimeError("Bad line: %s" % line)
156
                raise RuntimeError("Bad line: %s" % line)
157
           
157
           
158
            choices.append((res.group(2), res.group(3)))
158
            choices.append((res.group(2), res.group(3)))
159
            continue
159
            continue
160
       
160
       
161
        if (line.startswith('%')):
161
        if (line.startswith('%')):
162
            # Name of the option
162
            # Name of the option
163
            name = line[1:].strip()
163
            name = line[1:].strip()
164
            continue
164
            continue
165
       
165
       
166
        if ((line.startswith('#')) or (line == '\n')):
166
        if ((line.startswith('#')) or (line == '\n')):
167
            # Comment or empty line
167
            # Comment or empty line
168
            continue
168
            continue
169
       
169
       
170
       
170
       
171
        raise RuntimeError("Unknown syntax: %s" % line)
171
        raise RuntimeError("Unknown syntax: %s" % line)
172
   
172
   
173
    inf.close()
173
    inf.close()
174
 
174
 
175
def yes_no(default):
175
def yes_no(default):
176
    "Return '*' if yes, ' ' if no"
176
    "Return '*' if yes, ' ' if no"
177
   
177
   
178
    if (default == 'y'):
178
    if (default == 'y'):
179
        return '*'
179
        return '*'
180
   
180
   
181
    return ' '
181
    return ' '
182
 
182
 
183
def subchoice(screen, name, choices, default):
183
def subchoice(screen, name, choices, default):
184
    "Return choice of choices"
184
    "Return choice of choices"
185
   
185
   
186
    maxkey = 0
186
    maxkey = 0
187
    for key, val in choices:
187
    for key, val in choices:
188
        length = len(key)
188
        length = len(key)
189
        if (length > maxkey):
189
        if (length > maxkey):
190
            maxkey = length
190
            maxkey = length
191
   
191
   
192
    options = []
192
    options = []
193
    position = None
193
    position = None
194
    cnt = 0
194
    cnt = 0
195
    for key, val in choices:
195
    for key, val in choices:
196
        if ((default) and (key == default)):
196
        if ((default) and (key == default)):
197
            position = cnt
197
            position = cnt
198
       
198
       
199
        options.append(" %-*s  %s " % (maxkey, key, val))
199
        options.append(" %-*s  %s " % (maxkey, key, val))
200
        cnt += 1
200
        cnt += 1
201
   
201
   
202
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
202
    (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
203
   
203
   
204
    if (button == 'cancel'):
204
    if (button == 'cancel'):
205
        return None
205
        return None
206
   
206
   
207
    return choices[value][0]
207
    return choices[value][0]
208
 
208
 
209
def check_choices(defaults, ask_names):
209
def check_choices(defaults, ask_names):
210
    "Check whether all accessible variables have a default"
210
    "Check whether all accessible variables have a default"
211
   
211
   
212
    for varname, vartype, name, choices, cond in ask_names:
212
    for varname, vartype, name, choices, cond in ask_names:
213
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
213
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
214
            continue
214
            continue
215
       
215
       
216
        if (not defaults.has_key(varname)):
216
        if (not defaults.has_key(varname)):
217
            return False
217
            return False
218
   
218
   
219
    return True
219
    return True
220
 
220
 
221
def create_output(mkname, mcname, dfname, defaults, ask_names):
221
def create_output(mkname, mcname, dfname, defaults, ask_names):
222
    "Create output configuration"
222
    "Create output configuration"
223
   
223
   
224
    revision = commands.getoutput('svnversion . 2> /dev/null')
224
    revision = commands.getoutput('svnversion . 2> /dev/null')
225
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
225
    timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
226
   
226
   
227
    outmk = file(mkname, 'w')
227
    outmk = file(mkname, 'w')
228
    outmc = file(mcname, 'w')
228
    outmc = file(mcname, 'w')
229
    outdf = file(dfname, 'w')
229
    outdf = file(dfname, 'w')
230
   
230
   
231
    outmk.write('#########################################\n')
231
    outmk.write('#########################################\n')
232
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
232
    outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
233
    outmk.write('#########################################\n\n')
233
    outmk.write('#########################################\n\n')
234
   
234
   
235
    outmc.write('/***************************************\n')
235
    outmc.write('/***************************************\n')
236
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
236
    outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
237
    outmc.write(' ***************************************/\n\n')
237
    outmc.write(' ***************************************/\n\n')
238
   
238
   
239
    outdf.write('#########################################\n')
239
    outdf.write('#########################################\n')
240
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
240
    outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
241
    outdf.write('#########################################\n\n')
241
    outdf.write('#########################################\n\n')
242
    outdf.write('CONFIG_DEFS =')
242
    outdf.write('CONFIG_DEFS =')
243
   
243
   
244
    for varname, vartype, name, choices, cond in ask_names:
244
    for varname, vartype, name, choices, cond in ask_names:
245
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
245
        if ((cond) and (not check_condition(cond, defaults, ask_names))):
246
            continue
246
            continue
247
       
247
       
248
        if (not defaults.has_key(varname)):
248
        if (not defaults.has_key(varname)):
249
            default = ''
249
            default = ''
250
        else:
250
        else:
251
            default = defaults[varname]
251
            default = defaults[varname]
252
       
252
       
253
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
253
        outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
254
       
254
       
255
        if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")):
255
        if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")):
256
            if (default == "y"):
256
            if (default == "y"):
257
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
257
                outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
258
                outdf.write(' -D%s' % varname)
258
                outdf.write(' -D%s' % varname)
259
        else:
259
        else:
260
            outmc.write('/* %s */\n#define %s %s\n\n' % (name, varname, default))
260
            outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
261
            outdf.write(' -D%s=%s' % (varname, default))
261
            outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
262
   
262
   
263
    outmk.write('REVISION = %s\n' % revision)
263
    outmk.write('REVISION = %s\n' % revision)
264
    outmk.write('TIMESTAMP = %s\n' % timestamp)
264
    outmk.write('TIMESTAMP = %s\n' % timestamp)
265
   
265
   
266
    outmc.write('#define REVISION %s\n' % revision)
266
    outmc.write('#define REVISION %s\n' % revision)
267
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
267
    outmc.write('#define TIMESTAMP %s\n' % timestamp)
268
   
268
   
269
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
269
    outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
270
   
270
   
271
    outmk.close()
271
    outmk.close()
272
    outmc.close()
272
    outmc.close()
273
    outdf.close()
273
    outdf.close()
274
 
274
 
275
def main():
275
def main():
276
    defaults = {}
276
    defaults = {}
277
    ask_names = []
277
    ask_names = []
278
   
278
   
279
    # Parse configuration file
279
    # Parse configuration file
280
    parse_config(INPUT, ask_names)
280
    parse_config(INPUT, ask_names)
281
   
281
   
282
    # Read defaults from previous run
282
    # Read defaults from previous run
283
    if os.path.exists(MAKEFILE):
283
    if os.path.exists(MAKEFILE):
284
        read_defaults(MAKEFILE, defaults)
284
        read_defaults(MAKEFILE, defaults)
285
   
285
   
286
    # Default mode: only check defaults and regenerate configuration
286
    # Default mode: only check defaults and regenerate configuration
287
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
287
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
288
        if (check_choices(defaults, ask_names)):
288
        if (check_choices(defaults, ask_names)):
289
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
289
            create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
290
            return 0
290
            return 0
291
   
291
   
292
    # Check mode: only check defaults
292
    # Check mode: only check defaults
293
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
293
    if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
294
        if (check_choices(defaults, ask_names)):
294
        if (check_choices(defaults, ask_names)):
295
            return 0
295
            return 0
296
        return 1
296
        return 1
297
   
297
   
298
    screen = xtui.screen_init()
298
    screen = xtui.screen_init()
299
    try:
299
    try:
300
        selname = None
300
        selname = None
301
        while True:
301
        while True:
302
           
302
           
303
            options = []
303
            options = []
304
            opt2row = {}
304
            opt2row = {}
305
            position = None
305
            position = None
306
            cnt = 0
306
            cnt = 0
307
            for varname, vartype, name, choices, cond in ask_names:
307
            for varname, vartype, name, choices, cond in ask_names:
308
               
308
               
309
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
309
                if ((cond) and (not check_condition(cond, defaults, ask_names))):
310
                    continue
310
                    continue
311
               
311
               
312
                if (varname == selname):
312
                if (varname == selname):
313
                    position = cnt
313
                    position = cnt
314
               
314
               
315
                if (not defaults.has_key(varname)):
315
                if (not defaults.has_key(varname)):
316
                    default = None
316
                    default = None
317
                else:
317
                else:
318
                    default = defaults[varname]
318
                    default = defaults[varname]
319
               
319
               
320
                if (vartype == 'choice'):
320
                if (vartype == 'choice'):
321
                    # Check if the default is an acceptable value
321
                    # Check if the default is an acceptable value
322
                    if ((default) and (not default in [choice[0] for choice in choices])):
322
                    if ((default) and (not default in [choice[0] for choice in choices])):
323
                        default = None
323
                        default = None
324
                        defaults.pop(varname)
324
                        defaults.pop(varname)
325
                   
325
                   
326
                    # If there is just one option, use it
326
                    # If there is just one option, use it
327
                    if (len(choices) == 1):
327
                    if (len(choices) == 1):
328
                        defaults[varname] = choices[0][0]
328
                        defaults[varname] = choices[0][0]
329
                        continue
329
                        continue
330
                   
330
                   
331
                    options.append("     %s [%s] --> " % (name, default))
331
                    options.append("     %s [%s] --> " % (name, default))
332
                elif (vartype == 'y'):
332
                elif (vartype == 'y'):
333
                    defaults[varname] = 'y'
333
                    defaults[varname] = 'y'
334
                    continue
334
                    continue
335
                elif (vartype == 'y/n'):
335
                elif (vartype == 'y/n'):
336
                    if (default == None):
336
                    if (default == None):
337
                        default = 'y'
337
                        default = 'y'
338
                        defaults[varname] = default
338
                        defaults[varname] = default
339
                    options.append(" <%s> %s " % (yes_no(default), name))
339
                    options.append(" <%s> %s " % (yes_no(default), name))
340
                elif (vartype == 'n/y'):
340
                elif (vartype == 'n/y'):
341
                    if (default == None):
341
                    if (default == None):
342
                        default = 'n'
342
                        default = 'n'
343
                        defaults[varname] = default
343
                        defaults[varname] = default
344
                    options.append(" <%s> %s " % (yes_no(default), name))
344
                    options.append(" <%s> %s " % (yes_no(default), name))
345
                else:
345
                else:
346
                    raise RuntimeError("Unknown variable type: %s" % vartype)
346
                    raise RuntimeError("Unknown variable type: %s" % vartype)
347
               
347
               
348
                opt2row[cnt] = (varname, vartype, name, choices)
348
                opt2row[cnt] = (varname, vartype, name, choices)
349
               
349
               
350
                cnt += 1
350
                cnt += 1
351
           
351
           
352
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
352
            (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
353
           
353
           
354
            if (button == 'cancel'):
354
            if (button == 'cancel'):
355
                return 'Configuration canceled'
355
                return 'Configuration canceled'
356
           
356
           
357
            if (not opt2row.has_key(value)):
357
            if (not opt2row.has_key(value)):
358
                raise RuntimeError("Error selecting value: %s" % value)
358
                raise RuntimeError("Error selecting value: %s" % value)
359
           
359
           
360
            (selname, seltype, name, choices) = opt2row[value]
360
            (selname, seltype, name, choices) = opt2row[value]
361
           
361
           
362
            if (not defaults.has_key(selname)):
362
            if (not defaults.has_key(selname)):
363
                    default = None
363
                    default = None
364
            else:
364
            else:
365
                default = defaults[selname]
365
                default = defaults[selname]
366
           
366
           
367
            if (button == 'done'):
367
            if (button == 'done'):
368
                if (check_choices(defaults, ask_names)):
368
                if (check_choices(defaults, ask_names)):
369
                    break
369
                    break
370
                else:
370
                else:
371
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values.')
371
                    xtui.error_dialog(screen, 'Error', 'Some options have still undefined values.')
372
                    continue
372
                    continue
373
           
373
           
374
            if (seltype == 'choice'):
374
            if (seltype == 'choice'):
375
                defaults[selname] = subchoice(screen, name, choices, default)
375
                defaults[selname] = subchoice(screen, name, choices, default)
376
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
376
            elif ((seltype == 'y/n') or (seltype == 'n/y')):
377
                if (defaults[selname] == 'y'):
377
                if (defaults[selname] == 'y'):
378
                    defaults[selname] = 'n'
378
                    defaults[selname] = 'n'
379
                else:
379
                else:
380
                    defaults[selname] = 'y'
380
                    defaults[selname] = 'y'
381
    finally:
381
    finally:
382
        xtui.screen_done(screen)
382
        xtui.screen_done(screen)
383
   
383
   
384
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
384
    create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
385
    return 0
385
    return 0
386
 
386
 
387
if __name__ == '__main__':
387
if __name__ == '__main__':
388
    sys.exit(main())
388
    sys.exit(main())
389
 
389