- Timestamp:
- 2010-12-16T16:38:49Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7837101
- Parents:
- 8e58f94 (diff), eb221e5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- tools
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/autotool.py
r8e58f94 r7bdcc45 49 49 50 50 PACKAGE_BINUTILS = "usually part of binutils" 51 PACKAGE_GCC = "preferably version 4. 4.3or newer"51 PACKAGE_GCC = "preferably version 4.5.1 or newer" 52 52 PACKAGE_CROSS = "use tools/toolchain.sh to build the cross-compiler toolchain" 53 53 54 54 COMPILER_FAIL = "The compiler is probably not capable to compile HelenOS." 55 56 PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, value) \\ 55 COMPILER_WARNING = "The compilation of HelenOS might fail." 56 57 PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, strc, conc, value) \\ 57 58 asm volatile ( \\ 58 "AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t %[val]\\n" \\59 "AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t" strc "\\t" conc "\\t%[val]\\n" \\ 59 60 : \\ 60 61 : [val] "n" (value) \\ 61 62 ) 62 63 63 #define DECLARE_INTSIZE(tag, type) \\ 64 AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, sizeof(unsigned type)); \\ 65 AUTOTOOL_DECLARE("intsize", "signed", tag, #type, sizeof(signed type)) 64 #define STRING(arg) STRING_ARG(arg) 65 #define STRING_ARG(arg) #arg 66 67 #define DECLARE_BUILTIN_TYPE(tag, type) \\ 68 AUTOTOOL_DECLARE("builtin", "", tag, STRING(type), "", "", sizeof(type)); 69 70 #define DECLARE_INTSIZE(tag, type, strc, conc) \\ 71 AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, strc, conc, sizeof(unsigned type)); \\ 72 AUTOTOOL_DECLARE("intsize", "signed", tag, #type, strc, conc, sizeof(signed type)); 66 73 67 74 int main(int argc, char *argv[]) 68 75 { 76 #ifdef __SIZE_TYPE__ 77 DECLARE_BUILTIN_TYPE("size", __SIZE_TYPE__); 78 #endif 79 #ifdef __WCHAR_TYPE__ 80 DECLARE_BUILTIN_TYPE("wchar", __WCHAR_TYPE__); 81 #endif 82 #ifdef __WINT_TYPE__ 83 DECLARE_BUILTIN_TYPE("wint", __WINT_TYPE__); 84 #endif 69 85 """ 70 86 … … 96 112 97 113 sys.exit(1) 114 115 def print_warning(msg): 116 "Print a bold error message" 117 118 sys.stderr.write("\n") 119 sys.stderr.write("######################################################################\n") 120 sys.stderr.write("HelenOS build sanity check warning:\n") 121 sys.stderr.write("\n") 122 sys.stderr.write("%s\n" % "\n".join(msg)) 123 sys.stderr.write("######################################################################\n") 124 sys.stderr.write("\n") 125 126 time.sleep(5) 98 127 99 128 def sandbox_enter(): … … 186 215 check_app([common['STRIP'], "--version"], "GNU strip", details) 187 216 217 def decode_value(value): 218 "Decode integer value" 219 220 base = 10 221 222 if ((value.startswith('$')) or (value.startswith('#'))): 223 value = value[1:] 224 225 if (value.startswith('0x')): 226 value = value[2:] 227 base = 16 228 229 return int(value, base) 230 188 231 def probe_compiler(common, sizes): 189 232 "Generate, compile and parse probing source" … … 195 238 196 239 for typedef in sizes: 197 outf.write("\tDECLARE_INTSIZE(\"%s\", %s );\n" % (typedef['tag'], typedef['type']))240 outf.write("\tDECLARE_INTSIZE(\"%s\", %s, %s, %s);\n" % (typedef['tag'], typedef['type'], typedef['strc'], typedef['conc'])) 198 241 199 242 outf.write(PROBE_TAIL) … … 231 274 signed_tags = {} 232 275 276 unsigned_strcs = {} 277 signed_strcs = {} 278 279 unsigned_concs = {} 280 signed_concs = {} 281 282 builtins = {} 283 233 284 for j in range(len(lines)): 234 285 tokens = lines[j].strip().split("\t") … … 236 287 if (len(tokens) > 0): 237 288 if (tokens[0] == "AUTOTOOL_DECLARE"): 238 if (len(tokens) < 5):289 if (len(tokens) < 7): 239 290 print_error(["Malformed declaration in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL]) 240 291 … … 243 294 tag = tokens[3] 244 295 name = tokens[4] 245 value = tokens[5] 296 strc = tokens[5] 297 conc = tokens[6] 298 value = tokens[7] 246 299 247 300 if (category == "intsize"): 248 base = 10249 250 if ((value.startswith('$')) or (value.startswith('#'))):251 value = value[1:]252 253 if (value.startswith('0x')):254 value = value[2:]255 base = 16256 257 301 try: 258 value_int = int(value, base)302 value_int = decode_value(value) 259 303 except: 260 304 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL]) 261 305 262 306 if (subcategory == "unsigned"): 263 unsigned_sizes[ name] = value_int307 unsigned_sizes[value_int] = name 264 308 unsigned_tags[tag] = value_int 309 unsigned_strcs[value_int] = strc 310 unsigned_concs[value_int] = conc 265 311 elif (subcategory == "signed"): 266 signed_sizes[ name] = value_int312 signed_sizes[value_int] = name 267 313 signed_tags[tag] = value_int 314 signed_strcs[value_int] = strc 315 signed_concs[value_int] = conc 268 316 else: 269 317 print_error(["Unexpected keyword \"%s\" in \"%s\" on line %s." % (subcategory, PROBE_OUTPUT, j), COMPILER_FAIL]) 270 271 return {'unsigned_sizes' : unsigned_sizes, 'signed_sizes' : signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags} 272 273 def detect_uints(probe, bytes): 318 319 if (category == "builtin"): 320 try: 321 value_int = decode_value(value) 322 except: 323 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL]) 324 325 builtins[tag] = {'name': name, 'value': value_int} 326 327 return {'unsigned_sizes': unsigned_sizes, 'signed_sizes': signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags, 'unsigned_strcs': unsigned_strcs, 'signed_strcs': signed_strcs, 'unsigned_concs': unsigned_concs, 'signed_concs': signed_concs, 'builtins': builtins} 328 329 def detect_uints(probe, bytes, tags): 274 330 "Detect correct types for fixed-size integer types" 275 331 … … 278 334 279 335 for b in bytes: 336 if (not b in probe['unsigned_sizes']): 337 print_error(['Unable to find appropriate unsigned integer type for %u bytes' % b, 338 COMPILER_FAIL]) 339 340 if (not b in probe['signed_sizes']): 341 print_error(['Unable to find appropriate signed integer type for %u bytes' % b, 342 COMPILER_FAIL]) 343 344 if (not b in probe['unsigned_strcs']): 345 print_error(['Unable to find appropriate unsigned printf formatter for %u bytes' % b, 346 COMPILER_FAIL]) 347 348 if (not b in probe['signed_strcs']): 349 print_error(['Unable to find appropriate signed printf formatter for %u bytes' % b, 350 COMPILER_FAIL]) 351 352 if (not b in probe['unsigned_concs']): 353 print_error(['Unable to find appropriate unsigned literal macro for %u bytes' % b, 354 COMPILER_FAIL]) 355 356 if (not b in probe['signed_concs']): 357 print_error(['Unable to find appropriate signed literal macro for %u bytes' % b, 358 COMPILER_FAIL]) 359 360 typedefs.append({'oldtype': "unsigned %s" % probe['unsigned_sizes'][b], 'newtype': "uint%u_t" % (b * 8)}) 361 typedefs.append({'oldtype': "signed %s" % probe['signed_sizes'][b], 'newtype': "int%u_t" % (b * 8)}) 362 363 macros.append({'oldmacro': "\"%so\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIo%u" % (b * 8)}) 364 macros.append({'oldmacro': "\"%su\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIu%u" % (b * 8)}) 365 macros.append({'oldmacro': "\"%sx\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIx%u" % (b * 8)}) 366 macros.append({'oldmacro': "\"%sX\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIX%u" % (b * 8)}) 367 macros.append({'oldmacro': "\"%sd\"" % probe['signed_strcs'][b], 'newmacro': "PRId%u" % (b * 8)}) 368 369 name = probe['unsigned_concs'][b] 370 if ((name.startswith('@')) or (name == "")): 371 macros.append({'oldmacro': "c ## U", 'newmacro': "UINT%u_C(c)" % (b * 8)}) 372 else: 373 macros.append({'oldmacro': "c ## U%s" % name, 'newmacro': "UINT%u_C(c)" % (b * 8)}) 374 375 name = probe['unsigned_concs'][b] 376 if ((name.startswith('@')) or (name == "")): 377 macros.append({'oldmacro': "c", 'newmacro': "INT%u_C(c)" % (b * 8)}) 378 else: 379 macros.append({'oldmacro': "c ## %s" % name, 'newmacro': "INT%u_C(c)" % (b * 8)}) 380 381 for tag in tags: 382 newmacro = "U%s" % tag 383 if (not tag in probe['unsigned_tags']): 384 print_error(['Unable to find appropriate size macro for %s' % newmacro, 385 COMPILER_FAIL]) 386 387 oldmacro = "UINT%s" % (probe['unsigned_tags'][tag] * 8) 388 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro}) 389 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro}) 390 391 newmacro = tag 392 if (not tag in probe['unsigned_tags']): 393 print_error(['Unable to find appropriate size macro for %s' % newmacro, 394 COMPILER_FAIL]) 395 396 oldmacro = "INT%s" % (probe['signed_tags'][tag] * 8) 397 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro}) 398 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro}) 399 400 fnd = True 401 402 if (not 'wchar' in probe['builtins']): 403 print_warning(['The compiler does not provide the macro __WCHAR_TYPE__', 404 'for defining the compiler-native type wchar_t. We are', 405 'forced to define wchar_t as a hardwired type int32_t.', 406 COMPILER_WARNING]) 280 407 fnd = False 281 newtype = "uint%s_t" % (b * 8) 282 283 for name, value in probe['unsigned_sizes'].items(): 284 if (value == b): 285 oldtype = "unsigned %s" % name 286 typedefs.append({'oldtype' : oldtype, 'newtype' : newtype}) 287 fnd = True 288 break 289 290 if (not fnd): 291 print_error(['Unable to find appropriate integer type for %s' % newtype, 292 COMPILER_FAIL]) 293 294 408 409 if (probe['builtins']['wchar']['value'] != 4): 410 print_warning(['The compiler provided macro __WCHAR_TYPE__ for defining', 411 'the compiler-native type wchar_t is not compliant with', 412 'HelenOS. We are forced to define wchar_t as a hardwired', 413 'type int32_t.', 414 COMPILER_WARNING]) 295 415 fnd = False 296 newtype = "int%s_t" % (b * 8) 297 298 for name, value in probe['signed_sizes'].items(): 299 if (value == b): 300 oldtype = "signed %s" % name 301 typedefs.append({'oldtype' : oldtype, 'newtype' : newtype}) 302 fnd = True 303 break 304 305 if (not fnd): 306 print_error(['Unable to find appropriate integer type for %s' % newtype, 307 COMPILER_FAIL]) 308 309 for tag in ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG']: 310 fnd = False; 311 newmacro = "U%s" % tag 312 313 for name, value in probe['unsigned_tags'].items(): 314 if (name == tag): 315 oldmacro = "UINT%s" % (value * 8) 316 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro}) 317 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro}) 318 fnd = True 319 break 320 321 if (not fnd): 322 print_error(['Unable to find appropriate size macro for %s' % newmacro, 323 COMPILER_FAIL]) 324 325 fnd = False; 326 newmacro = tag 327 328 for name, value in probe['signed_tags'].items(): 329 if (name == tag): 330 oldmacro = "INT%s" % (value * 8) 331 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro}) 332 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro}) 333 fnd = True 334 break 335 336 if (not fnd): 337 print_error(['Unable to find appropriate size macro for %s' % newmacro, 338 COMPILER_FAIL]) 416 417 if (not fnd): 418 macros.append({'oldmacro': "int32_t", 'newmacro': "wchar_t"}) 419 else: 420 macros.append({'oldmacro': "__WCHAR_TYPE__", 'newmacro': "wchar_t"}) 421 422 fnd = True 423 424 if (not 'wint' in probe['builtins']): 425 print_warning(['The compiler does not provide the macro __WINT_TYPE__', 426 'for defining the compiler-native type wint_t. We are', 427 'forced to define wint_t as a hardwired type int32_t.', 428 COMPILER_WARNING]) 429 fnd = False 430 431 if (probe['builtins']['wint']['value'] != 4): 432 print_warning(['The compiler provided macro __WINT_TYPE__ for defining', 433 'the compiler-native type wint_t is not compliant with', 434 'HelenOS. We are forced to define wint_t as a hardwired', 435 'type int32_t.', 436 COMPILER_WARNING]) 437 fnd = False 438 439 if (not fnd): 440 macros.append({'oldmacro': "int32_t", 'newmacro': "wint_t"}) 441 else: 442 macros.append({'oldmacro': "__WINT_TYPE__", 'newmacro': "wint_t"}) 339 443 340 444 return {'macros': macros, 'typedefs': typedefs} … … 508 612 probe = probe_compiler(common, 509 613 [ 510 {'type': ' char', 'tag': 'CHAR'},511 {'type': ' short int', 'tag': 'SHORT'},512 {'type': 'int', 'tag': 'INT' },513 {'type': ' long int', 'tag': 'LONG'},514 {'type': ' long long int', 'tag': 'LLONG'}614 {'type': 'long long int', 'tag': 'LLONG', 'strc': '"ll"', 'conc': '"LL"'}, 615 {'type': 'long int', 'tag': 'LONG', 'strc': '"l"', 'conc': '"L"'}, 616 {'type': 'int', 'tag': 'INT', 'strc': '""', 'conc': '""'}, 617 {'type': 'short int', 'tag': 'SHORT', 'strc': '"h"', 'conc': '"@"'}, 618 {'type': 'char', 'tag': 'CHAR', 'strc': '"hh"', 'conc': '"@@"'} 515 619 ] 516 620 ) 517 621 518 maps = detect_uints(probe, [1, 2, 4, 8] )622 maps = detect_uints(probe, [1, 2, 4, 8], ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG']) 519 623 520 624 finally: -
tools/config.py
r8e58f94 r7bdcc45 3 3 # Copyright (c) 2006 Ondrej Palkovsky 4 4 # Copyright (c) 2009 Martin Decky 5 # Copyright (c) 2010 Jiri Svoboda 5 6 # All rights reserved. 6 7 # … … 40 41 import xtui 41 42 42 INPUT= sys.argv[1]43 RULES_FILE = sys.argv[1] 43 44 MAKEFILE = 'Makefile.config' 44 45 MACROS = 'config.h' 45 PRE CONF= 'defaults'46 47 def read_ defaults(fname, defaults):48 "Read saved values from last configuration run "46 PRESETS_DIR = 'defaults' 47 48 def read_config(fname, config): 49 "Read saved values from last configuration run or a preset file" 49 50 50 51 inf = open(fname, 'r') … … 52 53 for line in inf: 53 54 res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line) 54 if (res):55 defaults[res.group(1)] = res.group(2)55 if res: 56 config[res.group(1)] = res.group(2) 56 57 57 58 inf.close() 58 59 59 def check_condition(text, defaults, ask_names):60 def check_condition(text, config, rules): 60 61 "Check that the condition specified on input line is True (only CNF and DNF is supported)" 61 62 62 63 ctype = 'cnf' 63 64 64 if ( (')|' in text) or ('|(' in text)):65 if (')|' in text) or ('|(' in text): 65 66 ctype = 'dnf' 66 67 67 if (ctype == 'cnf'):68 if ctype == 'cnf': 68 69 conds = text.split('&') 69 70 else: … … 71 72 72 73 for cond in conds: 73 if (cond.startswith('(')) and (cond.endswith(')')):74 if cond.startswith('(') and cond.endswith(')'): 74 75 cond = cond[1:-1] 75 76 76 inside = check_inside(cond, defaults, ctype)77 inside = check_inside(cond, config, ctype) 77 78 78 79 if (ctype == 'cnf') and (not inside): 79 80 return False 80 81 81 if (ctype == 'dnf') and (inside):82 if (ctype == 'dnf') and inside: 82 83 return True 83 84 84 if (ctype == 'cnf'):85 if ctype == 'cnf': 85 86 return True 86 87 return False 87 88 88 def check_inside(text, defaults, ctype):89 def check_inside(text, config, ctype): 89 90 "Check for condition" 90 91 91 if (ctype == 'cnf'):92 if ctype == 'cnf': 92 93 conds = text.split('|') 93 94 else: … … 96 97 for cond in conds: 97 98 res = re.match(r'^(.*?)(!?=)(.*)$', cond) 98 if (not res):99 if not res: 99 100 raise RuntimeError("Invalid condition: %s" % cond) 100 101 … … 103 104 condval = res.group(3) 104 105 105 if (not condname in defaults):106 if not condname in config: 106 107 varval = '' 107 108 else: 108 varval = defaults[condname]109 varval = config[condname] 109 110 if (varval == '*'): 110 111 varval = 'y' 111 112 112 if (ctype == 'cnf'):113 if ctype == 'cnf': 113 114 if (oper == '=') and (condval == varval): 114 115 return True … … 123 124 return False 124 125 125 if (ctype == 'cnf'):126 if ctype == 'cnf': 126 127 return False 127 128 128 129 return True 129 130 130 def parse_ config(fname, ask_names):131 "Parse configurationfile"131 def parse_rules(fname, rules): 132 "Parse rules file" 132 133 133 134 inf = open(fname, 'r') … … 138 139 for line in inf: 139 140 140 if (line.startswith('!')):141 if line.startswith('!'): 141 142 # Ask a question 142 143 res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line) 143 144 144 if (not res):145 if not res: 145 146 raise RuntimeError("Weird line: %s" % line) 146 147 … … 149 150 vartype = res.group(3) 150 151 151 ask_names.append((varname, vartype, name, choices, cond))152 rules.append((varname, vartype, name, choices, cond)) 152 153 name = '' 153 154 choices = [] 154 155 continue 155 156 156 if (line.startswith('@')):157 if line.startswith('@'): 157 158 # Add new line into the 'choices' array 158 159 res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line) … … 164 165 continue 165 166 166 if (line.startswith('%')):167 if line.startswith('%'): 167 168 # Name of the option 168 169 name = line[1:].strip() 169 170 continue 170 171 171 if ((line.startswith('#')) or (line == '\n')):172 if line.startswith('#') or (line == '\n'): 172 173 # Comment or empty line 173 174 continue … … 181 182 "Return '*' if yes, ' ' if no" 182 183 183 if (default == 'y'):184 if default == 'y': 184 185 return '*' 185 186 … … 199 200 cnt = 0 200 201 for key, val in choices: 201 if ( (default) and (key == default)):202 if (default) and (key == default): 202 203 position = cnt 203 204 … … 207 208 (button, value) = xtui.choice_window(screen, name, 'Choose value', options, position) 208 209 209 if (button == 'cancel'):210 if button == 'cancel': 210 211 return None 211 212 212 213 return choices[value][0] 213 214 214 def check_choices(defaults, ask_names): 215 "Check whether all accessible variables have a default" 216 217 for varname, vartype, name, choices, cond in ask_names: 218 if ((cond) and (not check_condition(cond, defaults, ask_names))): 215 ## Infer and verify configuration values. 216 # 217 # Augment @a config with values that can be inferred, purge invalid ones 218 # and verify that all variables have a value (previously specified or inferred). 219 # 220 # @param config Configuration to work on 221 # @param rules Rules 222 # 223 # @return True if configuration is complete and valid, False 224 # otherwise. 225 # 226 def infer_verify_choices(config, rules): 227 "Infer and verify configuration values." 228 229 for rule in rules: 230 varname, vartype, name, choices, cond = rule 231 232 if cond and (not check_condition(cond, config, rules)): 219 233 continue 220 234 221 if (not varname in defaults): 235 if not varname in config: 236 value = None 237 else: 238 value = config[varname] 239 240 if not validate_rule_value(rule, value): 241 value = None 242 243 default = get_default_rule(rule) 244 245 # 246 # If we don't have a value but we do have 247 # a default, use it. 248 # 249 if value == None and default != None: 250 value = default 251 config[varname] = default 252 253 if not varname in config: 222 254 return False 223 255 224 256 return True 225 257 226 def create_output(mkname, mcname, defaults, ask_names): 258 ## Get default value from a rule. 259 def get_default_rule(rule): 260 varname, vartype, name, choices, cond = rule 261 262 default = None 263 264 if vartype == 'choice': 265 # If there is just one option, use it 266 if len(choices) == 1: 267 default = choices[0][0] 268 elif vartype == 'y': 269 default = '*' 270 elif vartype == 'n': 271 default = 'n' 272 elif vartype == 'y/n': 273 default = 'y' 274 elif vartype == 'n/y': 275 default = 'n' 276 else: 277 raise RuntimeError("Unknown variable type: %s" % vartype) 278 279 return default 280 281 ## Get option from a rule. 282 # 283 # @param rule Rule for a variable 284 # @param value Current value of the variable 285 # 286 # @return Option (string) to ask or None which means not to ask. 287 # 288 def get_rule_option(rule, value): 289 varname, vartype, name, choices, cond = rule 290 291 option = None 292 293 if vartype == 'choice': 294 # If there is just one option, don't ask 295 if len(choices) != 1: 296 if (value == None): 297 option = "? %s --> " % name 298 else: 299 option = " %s [%s] --> " % (name, value) 300 elif vartype == 'y': 301 pass 302 elif vartype == 'n': 303 pass 304 elif vartype == 'y/n': 305 option = " <%s> %s " % (yes_no(value), name) 306 elif vartype == 'n/y': 307 option =" <%s> %s " % (yes_no(value), name) 308 else: 309 raise RuntimeError("Unknown variable type: %s" % vartype) 310 311 return option 312 313 ## Check if variable value is valid. 314 # 315 # @param rule Rule for the variable 316 # @param value Value of the variable 317 # 318 # @return True if valid, False if not valid. 319 # 320 def validate_rule_value(rule, value): 321 varname, vartype, name, choices, cond = rule 322 323 if value == None: 324 return True 325 326 if vartype == 'choice': 327 if not value in [choice[0] for choice in choices]: 328 return False 329 elif vartype == 'y': 330 if value != 'y': 331 return False 332 elif vartype == 'n': 333 if value != 'n': 334 return False 335 elif vartype == 'y/n': 336 if not value in ['y', 'n']: 337 return False 338 elif vartype == 'n/y': 339 if not value in ['y', 'n']: 340 return False 341 else: 342 raise RuntimeError("Unknown variable type: %s" % vartype) 343 344 return True 345 346 def create_output(mkname, mcname, config, rules): 227 347 "Create output configuration" 228 348 … … 238 358 sys.stderr.write("failed\n") 239 359 240 if (len(version) == 3):360 if len(version) == 3: 241 361 revision = version[1] 242 if (version[0] != 1):362 if version[0] != 1: 243 363 revision += 'M' 244 364 revision += ' (%s)' % version[2] … … 259 379 defs = 'CONFIG_DEFS =' 260 380 261 for varname, vartype, name, choices, cond in ask_names:262 if ((cond) and (not check_condition(cond, defaults, ask_names))):381 for varname, vartype, name, choices, cond in rules: 382 if cond and (not check_condition(cond, config, rules)): 263 383 continue 264 384 265 if (not varname in defaults):266 default= ''385 if not varname in config: 386 value = '' 267 387 else: 268 default = defaults[varname]269 if ( default== '*'):270 default= 'y'271 272 outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))273 274 if ((vartype == "y") or (vartype == "n") or (vartype == "y/n") or (vartype == "n/y")):275 if (default == "y"):388 value = config[varname] 389 if (value == '*'): 390 value = 'y' 391 392 outmk.write('# %s\n%s = %s\n\n' % (name, varname, value)) 393 394 if vartype in ["y", "n", "y/n", "n/y"]: 395 if value == "y": 276 396 outmc.write('/* %s */\n#define %s\n\n' % (name, varname)) 277 397 defs += ' -D%s' % varname 278 398 else: 279 outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))280 defs += ' -D%s=%s -D%s_%s' % (varname, default, varname, default)281 282 if (revision is not None):399 outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, value, varname, value)) 400 defs += ' -D%s=%s -D%s_%s' % (varname, value, varname, value) 401 402 if revision is not None: 283 403 outmk.write('REVISION = %s\n' % revision) 284 404 outmc.write('#define REVISION %s\n' % revision) … … 299 419 return list 300 420 301 def read_preconfigured(root, fname, screen, defaults): 421 ## Ask user to choose a configuration profile. 422 # 423 def choose_profile(root, fname, screen, config): 302 424 options = [] 303 425 opt2path = {} … … 309 431 canon = os.path.join(path, fname) 310 432 311 if ((os.path.isdir(path)) and (os.path.exists(canon)) and (os.path.isfile(canon))):433 if os.path.isdir(path) and os.path.exists(canon) and os.path.isfile(canon): 312 434 subprofile = False 313 435 … … 317 439 subcanon = os.path.join(subpath, fname) 318 440 319 if ((os.path.isdir(subpath)) and (os.path.exists(subcanon)) and (os.path.isfile(subcanon))):441 if os.path.isdir(subpath) and os.path.exists(subcanon) and os.path.isfile(subcanon): 320 442 subprofile = True 321 443 options.append("%s (%s)" % (name, subname)) 322 opt2path[cnt] = (canon, subcanon)444 opt2path[cnt] = [name, subname] 323 445 cnt += 1 324 446 325 if (not subprofile):447 if not subprofile: 326 448 options.append(name) 327 opt2path[cnt] = (canon, None)449 opt2path[cnt] = [name] 328 450 cnt += 1 329 451 330 452 (button, value) = xtui.choice_window(screen, 'Load preconfigured defaults', 'Choose configuration profile', options, None) 331 453 332 if (button == 'cancel'):454 if button == 'cancel': 333 455 return None 334 456 335 read_defaults(opt2path[value][0], defaults) 336 if (opt2path[value][1] != None): 337 read_defaults(opt2path[value][1], defaults) 457 return opt2path[value] 458 459 ## Read presets from a configuration profile. 460 # 461 # @param profile Profile to load from (a list of string components) 462 # @param config Output configuration 463 # 464 def read_presets(profile, config): 465 path = os.path.join(PRESETS_DIR, profile[0], MAKEFILE) 466 read_config(path, config) 467 468 if len(profile) > 1: 469 path = os.path.join(PRESETS_DIR, profile[0], profile[1], MAKEFILE) 470 read_config(path, config) 471 472 ## Parse profile name (relative OS path) into a list of components. 473 # 474 # @param profile_name Relative path (using OS separator) 475 # @return List of components 476 # 477 def parse_profile_name(profile_name): 478 profile = [] 479 480 head, tail = os.path.split(profile_name) 481 if head != '': 482 profile.append(head) 483 484 profile.append(tail) 485 return profile 338 486 339 487 def main(): 340 defaults = {} 341 ask_names = [] 342 343 # Parse configuration file 344 parse_config(INPUT, ask_names) 345 346 # Read defaults from previous run 347 if os.path.exists(MAKEFILE): 348 read_defaults(MAKEFILE, defaults) 349 350 # Default mode: only check defaults and regenerate configuration 351 if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')): 352 if (check_choices(defaults, ask_names)): 353 create_output(MAKEFILE, MACROS, defaults, ask_names) 488 profile = None 489 config = {} 490 rules = [] 491 492 # Parse rules file 493 parse_rules(RULES_FILE, rules) 494 495 # Input configuration file can be specified on command line 496 # otherwise configuration from previous run is used. 497 if len(sys.argv) >= 4: 498 profile = parse_profile_name(sys.argv[3]) 499 read_presets(profile, config) 500 elif os.path.exists(MAKEFILE): 501 read_config(MAKEFILE, config) 502 503 # Default mode: check values and regenerate configuration files 504 if (len(sys.argv) >= 3) and (sys.argv[2] == 'default'): 505 if (infer_verify_choices(config, rules)): 506 create_output(MAKEFILE, MACROS, config, rules) 354 507 return 0 355 508 356 # Check mode: only check defaults 357 if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')): 358 if (check_choices(defaults, ask_names)): 509 # Hands-off mode: check values and regenerate configuration files, 510 # but no interactive fallback 511 if (len(sys.argv) >= 3) and (sys.argv[2] == 'hands-off'): 512 # We deliberately test sys.argv >= 4 because we do not want 513 # to read implicitly any possible previous run configuration 514 if len(sys.argv) < 4: 515 sys.stderr.write("Configuration error: No presets specified\n") 516 return 2 517 518 if (infer_verify_choices(config, rules)): 519 create_output(MAKEFILE, MACROS, config, rules) 520 return 0 521 522 sys.stderr.write("Configuration error: The presets are ambiguous\n") 523 return 1 524 525 # Check mode: only check configuration 526 if (len(sys.argv) >= 3) and (sys.argv[2] == 'check'): 527 if infer_verify_choices(config, rules): 359 528 return 0 360 529 return 1 … … 366 535 while True: 367 536 368 # Cancel out all defaults which have to be deduced369 for varname, vartype, name, choices, cond in ask_names:370 if ( (vartype == 'y') and (varname in defaults) and (defaults[varname] == '*')):371 defaults[varname] = None537 # Cancel out all values which have to be deduced 538 for varname, vartype, name, choices, cond in rules: 539 if (vartype == 'y') and (varname in config) and (config[varname] == '*'): 540 config[varname] = None 372 541 373 542 options = [] … … 377 546 options.append(" --- Load preconfigured defaults ... ") 378 547 379 for varname, vartype, name, choices, cond in ask_names: 380 381 if ((cond) and (not check_condition(cond, defaults, ask_names))): 548 for rule in rules: 549 varname, vartype, name, choices, cond = rule 550 551 if cond and (not check_condition(cond, config, rules)): 382 552 continue 383 553 384 if (varname == selname):554 if varname == selname: 385 555 position = cnt 386 556 387 if (not varname in defaults):388 default= None557 if not varname in config: 558 value = None 389 559 else: 390 default = defaults[varname]391 392 if (vartype == 'choice'):393 # Check if the default is an acceptable value394 if ((default) and (not default in [choice[0] for choice in choices])):395 default = None396 defaults.pop(varname) 397 398 # If there is just one option, use it399 if (len(choices) == 1):400 defaults[varname] = choices[0][0]401 continue402 403 if (default == None):404 options.append("? %s --> " % name)405 else:406 options.append(" %s [%s] --> " % (name, default))407 elif (vartype == 'y'):408 defaults[varname] = '*'560 value = config[varname] 561 562 if not validate_rule_value(rule, value): 563 value = None 564 565 default = get_default_rule(rule) 566 567 # 568 # If we don't have a value but we do have 569 # a default, use it. 570 # 571 if value == None and default != None: 572 value = default 573 config[varname] = default 574 575 option = get_rule_option(rule, value) 576 if option != None: 577 options.append(option) 578 else: 409 579 continue 410 elif (vartype == 'n'):411 defaults[varname] = 'n'412 continue413 elif (vartype == 'y/n'):414 if (default == None):415 default = 'y'416 defaults[varname] = default417 options.append(" <%s> %s " % (yes_no(default), name))418 elif (vartype == 'n/y'):419 if (default == None):420 default = 'n'421 defaults[varname] = default422 options.append(" <%s> %s " % (yes_no(default), name))423 else:424 raise RuntimeError("Unknown variable type: %s" % vartype)425 580 426 581 opt2row[cnt] = (varname, vartype, name, choices) … … 433 588 (button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position) 434 589 435 if (button == 'cancel'):590 if button == 'cancel': 436 591 return 'Configuration canceled' 437 592 438 if (button == 'done'):439 if ( check_choices(defaults, ask_names)):593 if button == 'done': 594 if (infer_verify_choices(config, rules)): 440 595 break 441 596 else: … … 443 598 continue 444 599 445 if (value == 0): 446 read_preconfigured(PRECONF, MAKEFILE, screen, defaults) 600 if value == 0: 601 profile = choose_profile(PRESETS_DIR, MAKEFILE, screen, config) 602 if profile != None: 603 read_presets(profile, config) 447 604 position = 1 448 605 continue 449 606 450 607 position = None 451 if (not value in opt2row):608 if not value in opt2row: 452 609 raise RuntimeError("Error selecting value: %s" % value) 453 610 454 611 (selname, seltype, name, choices) = opt2row[value] 455 612 456 if (not selname in defaults):457 default= None613 if not selname in config: 614 value = None 458 615 else: 459 default = defaults[selname]460 461 if (seltype == 'choice'):462 defaults[selname] = subchoice(screen, name, choices, default)463 elif ( (seltype == 'y/n') or (seltype == 'n/y')):464 if (defaults[selname] == 'y'):465 defaults[selname] = 'n'616 value = config[selname] 617 618 if seltype == 'choice': 619 config[selname] = subchoice(screen, name, choices, value) 620 elif (seltype == 'y/n') or (seltype == 'n/y'): 621 if config[selname] == 'y': 622 config[selname] = 'n' 466 623 else: 467 defaults[selname] = 'y'624 config[selname] = 'y' 468 625 finally: 469 626 xtui.screen_done(screen) 470 627 471 create_output(MAKEFILE, MACROS, defaults, ask_names)628 create_output(MAKEFILE, MACROS, config, rules) 472 629 return 0 473 630
Note:
See TracChangeset
for help on using the changeset viewer.