Changeset cf2f109 for menu/kconfiglib.py
- Timestamp:
- 06/15/2019 05:25:10 PM (5 years ago)
- Branches:
- ablfs-more, legacy, trunk
- Children:
- a4af6811
- Parents:
- 619b313
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
menu/kconfiglib.py
r619b313 rcf2f109 13 13 overview. 14 14 15 Since Kconfiglib 12.0.0, the library version is available in 16 kconfiglib.VERSION, which is a (<major>, <minor>, <patch>) tuple, e.g. 17 (12, 0, 0). 18 19 15 20 Using Kconfiglib on the Linux kernel with the Makefile targets 16 21 ============================================================== … … 48 53 ---------------- 49 54 50 This target runs the curses menuconfig interface with Python 3 (Python 2 is 51 currently not supported for the menuconfig). 55 This target runs the curses menuconfig interface with Python 3. As of 56 Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only 57 Python 3 was supported, so this was a backport). 58 59 60 make guiconfig 61 -------------- 62 63 This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3 64 are supported. To change the Python interpreter used, pass 65 PYTHONCMD=<executable> to 'make'. The default is 'python'. 52 66 53 67 … … 57 71 This target gives an interactive Python prompt where a Kconfig instance has 58 72 been preloaded and is available in 'kconf'. To change the Python interpreter 59 used, pass PYTHONCMD=<executable> to make. The default is "python".73 used, pass PYTHONCMD=<executable> to 'make'. The default is 'python'. 60 74 61 75 To get a feel for the API, try evaluating and printing the symbols in … … 383 397 384 398 'source' and 'rsource' accept glob patterns, sourcing all matching Kconfig 385 files. They require at least one matching file, throwing a KconfigError399 files. They require at least one matching file, raising a KconfigError 386 400 otherwise. 387 401 … … 438 452 such warnings are generated. 439 453 440 This warning can also be enabled/disabled via 441 Kconfig.enable/disable_undef_warnings().454 This warning can also be enabled/disabled via the Kconfig.warn_assign_undef 455 variable. 442 456 443 457 … … 530 544 # Get rid of some attribute lookups. These are obvious in context. 531 545 from glob import iglob 532 from os.path import dirname, exists, expandvars, isabs, islink, join, \ 533 relpath, split 546 from os.path import dirname, exists, expandvars, islink, join, realpath 547 548 549 VERSION = (12, 4, 0) 534 550 535 551 … … 620 636 appear multiple times. Use set() to get unique filenames. 621 637 622 Note: Using this for incremental builds is redundant. Kconfig.sync_deps() 623 already indirectly catches any file modifications that change the 624 configuration output. 638 Note that Kconfig.sync_deps() already indirectly catches any file 639 modifications that change configuration output. 625 640 626 641 env_vars: … … 692 707 Variable class. 693 708 709 warn: 710 Set this variable to True/False to enable/disable warnings. See 711 Kconfig.__init__(). 712 713 When 'warn' is False, the values of the other warning-related variables 714 are ignored. 715 716 This variable as well as the other warn* variables can be read to check 717 the current warning settings. 718 719 warn_to_stderr: 720 Set this variable to True/False to enable/disable warnings on stderr. See 721 Kconfig.__init__(). 722 723 warn_assign_undef: 724 Set this variable to True to generate warnings for assignments to 725 undefined symbols in configuration files. 726 727 This variable is False by default unless the KCONFIG_WARN_UNDEF_ASSIGN 728 environment variable was set to 'y' when the Kconfig instance was 729 created. 730 731 warn_assign_override: 732 Set this variable to True to generate warnings for multiple assignments 733 to the same symbol in configuration files, where the assignments set 734 different values (e.g. CONFIG_FOO=m followed by CONFIG_FOO=y, where the 735 last value would get used). 736 737 This variable is True by default. Disabling it might be useful when 738 merging configurations. 739 740 warn_assign_redun: 741 Like warn_assign_override, but for multiple assignments setting a symbol 742 to the same value. 743 744 This variable is True by default. Disabling it might be useful when 745 merging configurations. 746 694 747 warnings: 695 A list of strings containing all warnings that have been generated . This696 allows flexibility in how warnings are printed and processed.748 A list of strings containing all warnings that have been generated, for 749 cases where more flexibility is needed. 697 750 698 751 See the 'warn_to_stderr' parameter to Kconfig.__init__() and the 699 Kconfig.enable/disable_stderr_warnings() functions as well. Note that 700 warnings still get added to Kconfig.warnings when 'warn_to_stderr' is 701 True. 702 703 Just as for warnings printed to stderr, only optional warnings that are 704 enabled will get added to Kconfig.warnings. See the various 705 Kconfig.enable/disable_*_warnings() functions. 752 Kconfig.warn_to_stderr variable as well. Note that warnings still get 753 added to Kconfig.warnings when 'warn_to_stderr' is True. 754 755 Just as for warnings printed to stderr, only warnings that are enabled 756 will get added to Kconfig.warnings. See the various Kconfig.warn* 757 variables. 706 758 707 759 missing_syms: … … 742 794 "_functions", 743 795 "_set_match", 796 "_srctree_prefix", 744 797 "_unset_match", 745 "_warn_for_no_prompt", 746 "_warn_for_override", 747 "_warn_for_redun_assign", 748 "_warn_for_undef_assign", 749 "_warn_to_stderr", 750 "_warnings_enabled", 798 "_warn_no_prompt", 751 799 "choices", 752 800 "comments", … … 770 818 "unique_defined_syms", 771 819 "variables", 820 "warn", 821 "warn_assign_override", 822 "warn_assign_redun", 823 "warn_assign_undef", 824 "warn_to_stderr", 772 825 "warnings", 773 826 "y", … … 801 854 KCONFIG_WARN_UNDEF_ASSIGN). 802 855 803 Raises KconfigError on syntax errors, and (possibly a subclass of)804 IOError on IO errors ('errno', 'strerror', and 'filename' are856 Raises KconfigError on syntax/semantic errors, and (possibly a subclass 857 of) IOError on IO errors ('errno', 'strerror', and 'filename' are 805 858 available). Note that IOError can be caught as OSError on Python 3. 806 859 … … 821 874 warn (default: True): 822 875 True if warnings related to this configuration should be generated. 823 This can be changed later with Kconfig.enable/disable_warnings(). It876 This can be changed later by setting Kconfig.warn to True/False. It 824 877 is provided as a constructor argument since warnings might be 825 878 generated during parsing. 826 879 827 See the other Kconfig. enable_*_warnings() functions as well, which828 enable orsuppress certain warnings when warnings are enabled.880 See the other Kconfig.warn_* variables as well, which enable or 881 suppress certain warnings when warnings are enabled. 829 882 830 883 All generated warnings are added to the Kconfig.warnings list. See … … 835 888 added to Kconfig.warnings. 836 889 837 This can be changed later with838 Kconfig.enable/disable_stderr_warnings().890 This can be changed later by setting Kconfig.warn_to_stderr to 891 True/False. 839 892 840 893 encoding (default: "utf-8"): … … 853 906 """ 854 907 self.srctree = os.environ.get("srctree", "") 908 # A prefix we can reliably strip from glob() results to get a filename 909 # relative to $srctree. relpath() can cause issues for symlinks, 910 # because it assumes symlink/../foo is the same as foo/. 911 self._srctree_prefix = realpath(self.srctree) + os.sep 912 855 913 self.config_prefix = os.environ.get("CONFIG_", "CONFIG_") 856 914 … … 863 921 self.warnings = [] 864 922 865 self. _warnings_enabled= warn866 self. _warn_to_stderr = warn_to_stderr867 self. _warn_for_undef_assign= \923 self.warn = warn 924 self.warn_to_stderr = warn_to_stderr 925 self.warn_assign_undef = \ 868 926 os.environ.get("KCONFIG_WARN_UNDEF_ASSIGN") == "y" 869 self. _warn_for_redun_assign = self._warn_for_override= True927 self.warn_assign_override = self.warn_assign_redun = True 870 928 871 929 … … 1019 1077 1020 1078 1021 self._warn_ for_no_prompt = True1079 self._warn_no_prompt = True 1022 1080 1023 1081 self.mainmenu_text = self.top_node.prompt[0] … … 1039 1097 return None 1040 1098 1041 def load_config(self, filename=None, replace=True, verbose= True):1099 def load_config(self, filename=None, replace=True, verbose=None): 1042 1100 """ 1043 1101 Loads symbol values from a file in the .config format. Equivalent to … … 1087 1145 .config. Pass False to merge configurations. 1088 1146 1089 verbose (default: True): 1090 If True and filename is None (automatically infer configuration 1091 file), a message will be printed to stdout telling which file got 1092 loaded (or that no file got loaded). This is meant to reduce 1093 boilerplate in tools. 1094 1095 Returns True if an existing configuration was loaded (that didn't come 1096 from the 'option defconfig_list' symbol), and False otherwise. This is 1097 mostly useful in conjunction with filename=None, as True will always be 1098 returned otherwise. 1099 """ 1100 loaded_existing = True 1147 verbose (default: None): 1148 Limited backwards compatibility to prevent crashes. A warning is 1149 printed if anything but None is passed. 1150 1151 Prior to Kconfiglib 12.0.0, this option enabled printing of messages 1152 to stdout when 'filename' was None. A message is (always) returned 1153 now instead, which is more flexible. 1154 1155 Will probably be removed in some future version. 1156 1157 Returns a string with a message saying which file got loaded (or 1158 possibly that no file got loaded, when 'filename' is None). This is 1159 meant to reduce boilerplate in tools, which can do e.g. 1160 print(kconf.load_config()). The returned message distinguishes between 1161 loading (replace == True) and merging (replace == False). 1162 """ 1163 if verbose is not None: 1164 _warn_verbose_deprecated("load_config") 1165 1166 msg = None 1101 1167 if filename is None: 1102 1168 filename = standard_config_filename() 1103 if exists(filename): 1104 if verbose: 1105 print("Using existing configuration '{}' as base" 1106 .format(filename)) 1107 else: 1108 filename = self.defconfig_filename 1109 if filename is None: 1110 if verbose: 1111 print("Using default symbol values as base") 1112 return False 1113 1114 if verbose: 1115 print("Using default configuration found in '{}' as " 1116 "base".format(filename)) 1117 1118 loaded_existing = False 1169 if not exists(filename) and \ 1170 not exists(join(self.srctree, filename)): 1171 defconfig = self.defconfig_filename 1172 if defconfig is None: 1173 return "Using default symbol values (no '{}')" \ 1174 .format(filename) 1175 1176 msg = " default configuration '{}' (no '{}')" \ 1177 .format(defconfig, filename) 1178 filename = defconfig 1179 1180 if not msg: 1181 msg = " configuration '{}'".format(filename) 1119 1182 1120 1183 # Disable the warning about assigning to symbols without prompts. This 1121 1184 # is normal and expected within a .config file. 1122 self._warn_ for_no_prompt = False1123 1124 # This stub only exists to make sure _warn_ for_no_prompt gets reenabled1185 self._warn_no_prompt = False 1186 1187 # This stub only exists to make sure _warn_no_prompt gets reenabled 1125 1188 try: 1126 1189 self._load_config(filename, replace) … … 1128 1191 _decoding_error(e, filename) 1129 1192 finally: 1130 self._warn_ for_no_prompt = True1131 1132 return loaded_existing1193 self._warn_no_prompt = True 1194 1195 return ("Loaded" if replace else "Merged") + msg 1133 1196 1134 1197 def _load_config(self, filename, replace): … … 1251 1314 display_user_val = sym.user_value 1252 1315 1253 msg = '{} set more than once. Old value : "{}", new value:"{}".'.format(1316 msg = '{} set more than once. Old value "{}", new value "{}".'.format( 1254 1317 _name_and_loc(sym), display_user_val, val 1255 1318 ) 1256 1319 1257 1320 if display_user_val == val: 1258 self._warn_redun_assign(msg, filename, linenr) 1259 else: 1260 self._warn_override(msg, filename, linenr) 1321 if self.warn_assign_redun: 1322 self._warn(msg, filename, linenr) 1323 elif self.warn_assign_override: 1324 self._warn(msg, filename, linenr) 1261 1325 1262 1326 sym.set_value(val) … … 1278 1342 1279 1343 self.missing_syms.append((name, val)) 1280 1281 if self._warn_for_undef_assign: 1344 if self.warn_assign_undef: 1282 1345 self._warn( 1283 1346 "attempt to assign the value '{}' to the undefined symbol {}" … … 1294 1357 table implementation as of writing, and so won't match. 1295 1358 1359 If 'filename' exists and its contents is identical to what would get 1360 written out, it is left untouched. This avoids updating file metadata 1361 like the modification time and possibly triggering redundant work in 1362 build tools. 1363 1296 1364 filename: 1297 1365 Self-explanatory. … … 1302 1370 and include a final terminating newline. 1303 1371 """ 1304 with self._open(filename, "w") as f: 1305 f.write(header) 1306 1307 for sym in self.unique_defined_syms: 1308 # Note: _write_to_conf is determined when the value is 1309 # calculated. This is a hidden function call due to 1310 # property magic. 1311 val = sym.str_value 1312 if sym._write_to_conf: 1313 if sym.orig_type in _BOOL_TRISTATE: 1314 if val != "n": 1315 f.write("#define {}{}{} 1\n" 1316 .format(self.config_prefix, sym.name, 1317 "_MODULE" if val == "m" else "")) 1318 1319 elif sym.orig_type is STRING: 1320 f.write('#define {}{} "{}"\n' 1321 .format(self.config_prefix, sym.name, 1322 escape(val))) 1323 1324 else: # sym.orig_type in _INT_HEX: 1325 if sym.orig_type is HEX and \ 1326 not val.startswith(("0x", "0X")): 1327 val = "0x" + val 1328 1329 f.write("#define {}{} {}\n" 1330 .format(self.config_prefix, sym.name, val)) 1372 self._write_if_changed(filename, self._autoconf_contents(header)) 1373 1374 def _autoconf_contents(self, header): 1375 # write_autoconf() helper. Returns the contents to write as a string, 1376 # with 'header' at the beginning. 1377 1378 # "".join()ed later 1379 chunks = [header] 1380 add = chunks.append 1381 1382 for sym in self.unique_defined_syms: 1383 # _write_to_conf is determined when the value is calculated. This 1384 # is a hidden function call due to property magic. 1385 val = sym.str_value 1386 if not sym._write_to_conf: 1387 continue 1388 1389 if sym.orig_type in _BOOL_TRISTATE: 1390 if val == "y": 1391 add("#define {}{} 1\n" 1392 .format(self.config_prefix, sym.name)) 1393 elif val == "m": 1394 add("#define {}{}_MODULE 1\n" 1395 .format(self.config_prefix, sym.name)) 1396 1397 elif sym.orig_type is STRING: 1398 add('#define {}{} "{}"\n' 1399 .format(self.config_prefix, sym.name, escape(val))) 1400 1401 else: # sym.orig_type in _INT_HEX: 1402 if sym.orig_type is HEX and \ 1403 not val.startswith(("0x", "0X")): 1404 val = "0x" + val 1405 1406 add("#define {}{} {}\n" 1407 .format(self.config_prefix, sym.name, val)) 1408 1409 return "".join(chunks) 1331 1410 1332 1411 def write_config(self, filename=None, 1333 1412 header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n", 1334 save_old=True, verbose= True):1413 save_old=True, verbose=None): 1335 1414 r""" 1336 1415 Writes out symbol values in the .config format. The format matches the … … 1345 1424 understand which symbols get written out. 1346 1425 1426 If 'filename' exists and its contents is identical to what would get 1427 written out, it is left untouched. This avoids updating file metadata 1428 like the modification time and possibly triggering redundant work in 1429 build tools. 1430 1347 1431 filename (default: None): 1348 1432 Filename to save configuration to (a string). 1349 1433 1350 If None (the default), the filename in the theenvironment variable1434 If None (the default), the filename in the environment variable 1351 1435 KCONFIG_CONFIG is used if set, and ".config" otherwise. See 1352 1436 standard_config_filename(). … … 1359 1443 save_old (default: True): 1360 1444 If True and <filename> already exists, a copy of it will be saved to 1361 .<filename>.old in the same directory before the new configuration is 1362 written. The leading dot is added only if the filename doesn't 1363 already start with a dot. 1364 1365 Errors are silently ignored if .<filename>.old cannot be written 1366 (e.g. due to being a directory). 1367 1368 verbose (default: True): 1369 If True and filename is None (automatically infer configuration 1370 file), a message will be printed to stdout telling which file got 1371 written. This is meant to reduce boilerplate in tools. 1372 """ 1445 <filename>.old in the same directory before the new configuration is 1446 written. 1447 1448 Errors are silently ignored if <filename>.old cannot be written (e.g. 1449 due to being a directory, or <filename> being something like 1450 /dev/null). 1451 1452 verbose (default: None): 1453 Limited backwards compatibility to prevent crashes. A warning is 1454 printed if anything but None is passed. 1455 1456 Prior to Kconfiglib 12.0.0, this option enabled printing of messages 1457 to stdout when 'filename' was None. A message is (always) returned 1458 now instead, which is more flexible. 1459 1460 Will probably be removed in some future version. 1461 1462 Returns a string with a message saying which file got saved. This is 1463 meant to reduce boilerplate in tools, which can do e.g. 1464 print(kconf.write_config()). 1465 """ 1466 if verbose is not None: 1467 _warn_verbose_deprecated("write_config") 1468 1373 1469 if filename is None: 1374 1470 filename = standard_config_filename() 1375 else: 1376 verbose = False 1471 1472 contents = self._config_contents(header) 1473 if self._contents_eq(filename, contents): 1474 return "No change to '{}'".format(filename) 1377 1475 1378 1476 if save_old: … … 1380 1478 1381 1479 with self._open(filename, "w") as f: 1382 f.write(header) 1383 1384 for node in self.node_iter(unique_syms=True): 1385 item = node.item 1386 1387 if item.__class__ is Symbol: 1388 f.write(item.config_string) 1389 1390 elif expr_value(node.dep) and \ 1391 ((item is MENU and expr_value(node.visibility)) or 1392 item is COMMENT): 1393 1394 f.write("\n#\n# {}\n#\n".format(node.prompt[0])) 1395 1396 if verbose: 1397 print("Configuration written to '{}'".format(filename)) 1480 f.write(contents) 1481 1482 return "Configuration saved to '{}'".format(filename) 1483 1484 def _config_contents(self, header): 1485 # write_config() helper. Returns the contents to write as a string, 1486 # with 'header' at the beginning. 1487 # 1488 # More memory friendly would be to 'yield' the strings and 1489 # "".join(_config_contents()), but it was a bit slower on my system. 1490 1491 # node_iter() was used here before commit 3aea9f7 ("Add '# end of 1492 # <menu>' after menus in .config"). Those comments get tricky to 1493 # implement with it. 1494 1495 for sym in self.unique_defined_syms: 1496 sym._visited = False 1497 1498 # Did we just print an '# end of ...' comment? 1499 after_end_comment = False 1500 1501 # "".join()ed later 1502 chunks = [header] 1503 add = chunks.append 1504 1505 node = self.top_node 1506 while 1: 1507 # Jump to the next node with an iterative tree walk 1508 if node.list: 1509 node = node.list 1510 elif node.next: 1511 node = node.next 1512 else: 1513 while node.parent: 1514 node = node.parent 1515 1516 # Add a comment when leaving visible menus 1517 if node.item is MENU and expr_value(node.dep) and \ 1518 expr_value(node.visibility) and \ 1519 node is not self.top_node: 1520 add("# end of {}\n".format(node.prompt[0])) 1521 after_end_comment = True 1522 1523 if node.next: 1524 node = node.next 1525 break 1526 else: 1527 # No more nodes 1528 return "".join(chunks) 1529 1530 # Generate configuration output for the node 1531 1532 item = node.item 1533 1534 if item.__class__ is Symbol: 1535 if item._visited: 1536 continue 1537 item._visited = True 1538 1539 conf_string = item.config_string 1540 if not conf_string: 1541 continue 1542 1543 if after_end_comment: 1544 # Add a blank line before the first symbol printed after an 1545 # '# end of ...' comment 1546 after_end_comment = False 1547 add("\n") 1548 add(conf_string) 1549 1550 elif expr_value(node.dep) and \ 1551 ((item is MENU and expr_value(node.visibility)) or 1552 item is COMMENT): 1553 1554 add("\n#\n# {}\n#\n".format(node.prompt[0])) 1555 after_end_comment = False 1398 1556 1399 1557 def write_min_config(self, filename, … … 1417 1575 would usually want each line to start with '#' to make it a comment, 1418 1576 and include a final terminating newline. 1419 """ 1577 1578 Returns a string with a message saying which file got saved. This is 1579 meant to reduce boilerplate in tools, which can do e.g. 1580 print(kconf.write_min_config()). 1581 """ 1582 contents = self._min_config_contents(header) 1583 if self._contents_eq(filename, contents): 1584 return "No change to '{}'".format(filename) 1585 1420 1586 with self._open(filename, "w") as f: 1421 f.write(header) 1422 1423 for sym in self.unique_defined_syms: 1424 # Skip symbols that cannot be changed. Only check 1425 # non-choice symbols, as selects don't affect choice 1426 # symbols. 1427 if not sym.choice and \ 1428 sym.visibility <= expr_value(sym.rev_dep): 1429 continue 1430 1431 # Skip symbols whose value matches their default 1432 if sym.str_value == sym._str_default(): 1433 continue 1434 1435 # Skip symbols that would be selected by default in a 1436 # choice, unless the choice is optional or the symbol type 1437 # isn't bool (it might be possible to set the choice mode 1438 # to n or the symbol to m in those cases). 1439 if sym.choice and \ 1440 not sym.choice.is_optional and \ 1441 sym.choice._get_selection_from_defaults() is sym and \ 1442 sym.orig_type is BOOL and \ 1443 sym.tri_value == 2: 1444 continue 1445 1446 f.write(sym.config_string) 1587 f.write(contents) 1588 1589 return "Minimal configuration saved to '{}'".format(filename) 1590 1591 def _min_config_contents(self, header): 1592 # write_min_config() helper. Returns the contents to write as a string, 1593 # with 'header' at the beginning. 1594 1595 chunks = [header] 1596 add = chunks.append 1597 1598 for sym in self.unique_defined_syms: 1599 # Skip symbols that cannot be changed. Only check 1600 # non-choice symbols, as selects don't affect choice 1601 # symbols. 1602 if not sym.choice and \ 1603 sym.visibility <= expr_value(sym.rev_dep): 1604 continue 1605 1606 # Skip symbols whose value matches their default 1607 if sym.str_value == sym._str_default(): 1608 continue 1609 1610 # Skip symbols that would be selected by default in a 1611 # choice, unless the choice is optional or the symbol type 1612 # isn't bool (it might be possible to set the choice mode 1613 # to n or the symbol to m in those cases). 1614 if sym.choice and \ 1615 not sym.choice.is_optional and \ 1616 sym.choice._get_selection_from_defaults() is sym and \ 1617 sym.orig_type is BOOL and \ 1618 sym.tri_value == 2: 1619 continue 1620 1621 add(sym.config_string) 1622 1623 return "".join(chunks) 1447 1624 1448 1625 def sync_deps(self, path): … … 1485 1662 track of them for the next build. 1486 1663 1664 If auto.conf exists and its contents is identical to what would 1665 get written out, it is left untouched. This avoids updating file 1666 metadata like the modification time and possibly triggering 1667 redundant work in build tools. 1668 1487 1669 1488 1670 The last piece of the puzzle is knowing what symbols each source file … … 1503 1685 os.mkdir(path, 0o755) 1504 1686 1505 # This setup makes sure that at least the current working directory1506 # gets reset if things fail1507 prev_dir = os.getcwd()1508 try:1509 # cd'ing into the symbol file directory simplifies1510 # _sync_deps() and saves some work1511 os.chdir(path)1512 self._sync_deps()1513 finally:1514 os.chdir(prev_dir)1515 1516 def _sync_deps(self):1517 1687 # Load old values from auto.conf, if any 1518 self._load_old_vals( )1688 self._load_old_vals(path) 1519 1689 1520 1690 for sym in self.unique_defined_syms: 1521 # Note: _write_to_conf is determined when the value is 1522 # calculated. This is a hidden function call due to 1523 # property magic. 1691 # _write_to_conf is determined when the value is calculated. This 1692 # is a hidden function call due to property magic. 1524 1693 val = sym.str_value 1525 1694 1526 # Note: n tristate values do not get written to auto.conf and1527 # autoconf.h,making a missing symbol logically equivalent to n1695 # n tristate values do not get written to auto.conf and autoconf.h, 1696 # making a missing symbol logically equivalent to n 1528 1697 1529 1698 if sym._write_to_conf: … … 1547 1716 1548 1717 # 'sym' has a new value. Flag it. 1549 _touch_dep_file( sym.name)1718 _touch_dep_file(path, sym.name) 1550 1719 1551 1720 # Remember the current values as the "new old" values. … … 1554 1723 # putting it last means _sync_deps() can be safely rerun if it fails 1555 1724 # before this point. 1556 self._write_old_vals() 1557 1558 def _write_old_vals(self): 1725 self._write_old_vals(path) 1726 1727 def _load_old_vals(self, path): 1728 # Loads old symbol values from auto.conf into a dedicated 1729 # Symbol._old_val field. Mirrors load_config(). 1730 # 1731 # The extra field could be avoided with some trickery involving dumping 1732 # symbol values and restoring them later, but this is simpler and 1733 # faster. The C tools also use a dedicated field for this purpose. 1734 1735 for sym in self.unique_defined_syms: 1736 sym._old_val = None 1737 1738 try: 1739 auto_conf = self._open(join(path, "auto.conf"), "r") 1740 except IOError as e: 1741 if e.errno == errno.ENOENT: 1742 # No old values 1743 return 1744 raise 1745 1746 with auto_conf as f: 1747 for line in f: 1748 match = self._set_match(line) 1749 if not match: 1750 # We only expect CONFIG_FOO=... (and possibly a header 1751 # comment) in auto.conf 1752 continue 1753 1754 name, val = match.groups() 1755 if name in self.syms: 1756 sym = self.syms[name] 1757 1758 if sym.orig_type is STRING: 1759 match = _conf_string_match(val) 1760 if not match: 1761 continue 1762 val = unescape(match.group(1)) 1763 1764 self.syms[name]._old_val = val 1765 else: 1766 # Flag that the symbol no longer exists, in 1767 # case something still depends on it 1768 _touch_dep_file(path, name) 1769 1770 def _write_old_vals(self, path): 1559 1771 # Helper for writing auto.conf. Basically just a simplified 1560 1772 # write_config() that doesn't write any comments (including … … 1566 1778 # by passing a flag to it, plus we only need to look at symbols here. 1567 1779 1568 with self._open("auto.conf", "w") as f: 1569 for sym in self.unique_defined_syms: 1570 if not (sym.orig_type in _BOOL_TRISTATE and not sym.tri_value): 1571 f.write(sym.config_string) 1572 1573 def _load_old_vals(self): 1574 # Loads old symbol values from auto.conf into a dedicated 1575 # Symbol._old_val field. Mirrors load_config(). 1576 # 1577 # The extra field could be avoided with some trickery involving dumping 1578 # symbol values and restoring them later, but this is simpler and 1579 # faster. The C tools also use a dedicated field for this purpose. 1580 1581 for sym in self.unique_defined_syms: 1582 sym._old_val = None 1583 1584 if not exists("auto.conf"): 1585 # No old values 1586 return 1587 1588 with self._open("auto.conf", "r") as f: 1589 for line in f: 1590 match = self._set_match(line) 1591 if not match: 1592 # We only expect CONFIG_FOO=... (and possibly a header 1593 # comment) in auto.conf 1594 continue 1595 1596 name, val = match.groups() 1597 if name in self.syms: 1598 sym = self.syms[name] 1599 1600 if sym.orig_type is STRING: 1601 match = _conf_string_match(val) 1602 if not match: 1603 continue 1604 val = unescape(match.group(1)) 1605 1606 self.syms[name]._old_val = val 1607 else: 1608 # Flag that the symbol no longer exists, in 1609 # case something still depends on it 1610 _touch_dep_file(name) 1780 self._write_if_changed( 1781 os.path.join(path, "auto.conf"), 1782 self._old_vals_contents()) 1783 1784 def _old_vals_contents(self): 1785 # _write_old_vals() helper. Returns the contents to write as a string. 1786 1787 # Temporary list instead of generator makes this a bit faster 1788 return "".join([ 1789 sym.config_string for sym in self.unique_defined_syms 1790 if not (sym.orig_type in _BOOL_TRISTATE and not sym.tri_value) 1791 ]) 1611 1792 1612 1793 def node_iter(self, unique_syms=False): … … 1686 1867 self._filename = None 1687 1868 1688 # Don't include the "if " from below to avoid giving confusing error1689 # messages1869 self._tokens = self._tokenize("if " + s) 1870 # Strip "if " to avoid giving confusing error messages 1690 1871 self._line = s 1691 self._tokens = self._tokenize("if " + s)1692 1872 self._tokens_i = 1 # Skip the 'if' token 1693 1873 … … 1696 1876 def unset_values(self): 1697 1877 """ 1698 Re sets the user values of all symbols, as if Kconfig.load_config() or1699 Symbol.set_value() had never been called.1700 """ 1701 self._warn_ for_no_prompt = False1878 Removes any user values from all symbols, as if Kconfig.load_config() 1879 or Symbol.set_value() had never been called. 1880 """ 1881 self._warn_no_prompt = False 1702 1882 try: 1703 1883 # set_value() already rejects undefined symbols, and they don't … … 1710 1890 choice.unset_value() 1711 1891 finally: 1712 self._warn_ for_no_prompt = True1892 self._warn_no_prompt = True 1713 1893 1714 1894 def enable_warnings(self): 1715 1895 """ 1716 See Kconfig.__init__(). 1717 """ 1718 self._warnings_enabled = True 1896 Do 'Kconfig.warn = True' instead. Maintained for backwards 1897 compatibility. 1898 """ 1899 self.warn = True 1719 1900 1720 1901 def disable_warnings(self): 1721 1902 """ 1722 See Kconfig.__init__(). 1723 """ 1724 self._warnings_enabled = False 1903 Do 'Kconfig.warn = False' instead. Maintained for backwards 1904 compatibility. 1905 """ 1906 self.warn = False 1725 1907 1726 1908 def enable_stderr_warnings(self): 1727 1909 """ 1728 See Kconfig.__init__(). 1729 """ 1730 self._warn_to_stderr = True 1910 Do 'Kconfig.warn_to_stderr = True' instead. Maintained for backwards 1911 compatibility. 1912 """ 1913 self.warn_to_stderr = True 1731 1914 1732 1915 def disable_stderr_warnings(self): 1733 1916 """ 1734 See Kconfig.__init__(). 1735 """ 1736 self._warn_to_stderr = False 1917 Do 'Kconfig.warn_to_stderr = False' instead. Maintained for backwards 1918 compatibility. 1919 """ 1920 self.warn_to_stderr = False 1737 1921 1738 1922 def enable_undef_warnings(self): 1739 1923 """ 1740 Enables warnings for assignments to undefined symbols. Disabled by 1741 default unless the KCONFIG_WARN_UNDEF_ASSIGN environment variable was 1742 set to 'y' when the Kconfig instance was created. 1743 """ 1744 self._warn_for_undef_assign = True 1924 Do 'Kconfig.warn_assign_undef = True' instead. Maintained for backwards 1925 compatibility. 1926 """ 1927 self.warn_assign_undef = True 1745 1928 1746 1929 def disable_undef_warnings(self): 1747 1930 """ 1748 See enable_undef_assign(). 1749 """ 1750 self._warn_for_undef_assign = False 1931 Do 'Kconfig.warn_assign_undef = False' instead. Maintained for 1932 backwards compatibility. 1933 """ 1934 self.warn_assign_undef = False 1751 1935 1752 1936 def enable_override_warnings(self): 1753 1937 """ 1754 Enables warnings for duplicated assignments in .config files that set 1755 different values (e.g. CONFIG_FOO=m followed by CONFIG_FOO=y, where 1756 the last value set is used). 1757 1758 These warnings are enabled by default. Disabling them might be helpful 1759 in certain cases when merging configurations. 1760 """ 1761 self._warn_for_override = True 1938 Do 'Kconfig.warn_assign_override = True' instead. Maintained for 1939 backwards compatibility. 1940 """ 1941 self.warn_assign_override = True 1762 1942 1763 1943 def disable_override_warnings(self): 1764 1944 """ 1765 See enable_override_warnings(). 1766 """ 1767 self._warn_for_override = False 1945 Do 'Kconfig.warn_assign_override = False' instead. Maintained for 1946 backwards compatibility. 1947 """ 1948 self.warn_assign_override = False 1768 1949 1769 1950 def enable_redun_warnings(self): 1770 1951 """ 1771 Enables warnings for duplicated assignments in .config files that all 1772 set the same value. 1773 1774 These warnings are enabled by default. Disabling them might be helpful 1775 in certain cases when merging configurations. 1776 """ 1777 self._warn_for_redun_assign = True 1952 Do 'Kconfig.warn_assign_redun = True' instead. Maintained for backwards 1953 compatibility. 1954 """ 1955 self.warn_assign_redun = True 1778 1956 1779 1957 def disable_redun_warnings(self): 1780 1958 """ 1781 See enable_redun_warnings(). 1782 """ 1783 self._warn_for_redun_assign = False 1959 Do 'Kconfig.warn_assign_redun = False' instead. Maintained for 1960 backwards compatibility. 1961 """ 1962 self.warn_assign_redun = False 1784 1963 1785 1964 def __repr__(self): … … 1788 1967 evaluated on e.g. the interactive Python prompt. 1789 1968 """ 1969 def status(flag): 1970 return "enabled" if flag else "disabled" 1971 1790 1972 return "<{}>".format(", ".join(( 1791 1973 "configuration with {} symbols".format(len(self.syms)), … … 1794 1976 'srctree "{}"'.format(self.srctree), 1795 1977 'config symbol prefix "{}"'.format(self.config_prefix), 1796 "warnings " + 1797 ("enabled" if self._warnings_enabled else "disabled"), 1798 "printing of warnings to stderr " + 1799 ("enabled" if self._warn_to_stderr else "disabled"), 1978 "warnings " + status(self.warn), 1979 "printing of warnings to stderr " + status(self.warn_to_stderr), 1800 1980 "undef. symbol assignment warnings " + 1801 ("enabled" if self._warn_for_undef_assign else "disabled"), 1981 status(self.warn_assign_undef), 1982 "overriding symbol assignment warnings " + 1983 status(self.warn_assign_override), 1802 1984 "redundant symbol assignment warnings " + 1803 ("enabled" if self._warn_for_redun_assign else "disabled")1985 status(self.warn_assign_redun) 1804 1986 ))) 1805 1987 … … 1839 2021 else "unset or blank")) 1840 2022 1841 def _enter_file(self, f ull_filename, rel_filename):2023 def _enter_file(self, filename): 1842 2024 # Jumps to the beginning of a sourced Kconfig file, saving the previous 1843 2025 # position and file object. 1844 2026 # 1845 # full_filename: 1846 # Actual path to the file. 1847 # 1848 # rel_filename: 1849 # File path with $srctree prefix stripped, stored in e.g. 1850 # self._filename (which makes it indirectly show up in 1851 # MenuNode.filename). Equals full_filename for absolute paths. 2027 # filename: 2028 # Absolute path to file 2029 2030 # Path relative to $srctree, stored in e.g. self._filename 2031 # (which makes it indirectly show up in MenuNode.filename). Equals 2032 # 'filename' for absolute paths passed to 'source'. 2033 if filename.startswith(self._srctree_prefix): 2034 # Relative path (or a redundant absolute path to within $srctree, 2035 # but it's probably fine to reduce those too) 2036 rel_filename = filename[len(self._srctree_prefix):] 2037 else: 2038 # Absolute path 2039 rel_filename = filename 1852 2040 1853 2041 self.kconfig_filenames.append(rel_filename) … … 1884 2072 for name, linenr in self._include_path))) 1885 2073 1886 # Note: We already know that the file exists1887 1888 2074 try: 1889 self._readline = self._open(f ull_filename, "r").readline2075 self._readline = self._open(filename, "r").readline 1890 2076 except IOError as e: 2077 # We already know that the file exists 1891 2078 raise _KconfigIOError( 1892 e, "{}:{}: Could not open '{}' ({}: {})" 1893 .format(self._filename, self._linenr, full_filename, 2079 e, "{}:{}: Could not open '{}' (in '{}') ({}: {})" 2080 .format(self._filename, self._linenr, filename, 2081 self._line.strip(), 1894 2082 errno.errorcode[e.errno], e.strerror)) 1895 2083 … … 1921 2109 return True 1922 2110 1923 # Note: readline() returns '' over and over at EOF, which we rely on1924 # for helptexts at the end of files (see _line_after_help())2111 # readline() returns '' over and over at EOF, which we rely on for help 2112 # texts at the end of files (see _line_after_help()) 1925 2113 line = self._readline() 1926 2114 if not line: … … 1933 2121 self._linenr += 1 1934 2122 1935 self._line = line # Used for error reporting1936 2123 self._tokens = self._tokenize(line) 1937 2124 # Initialize to 1 instead of 0 to factor out code from _parse_block() … … 1955 2142 self._linenr += 1 1956 2143 1957 self._line = line1958 2144 self._tokens = self._tokenize(line) 1959 2145 self._reuse_tokens = True 1960 2146 2147 def _write_if_changed(self, filename, contents): 2148 # Writes 'contents' into 'filename', but only if it differs from the 2149 # current contents of the file. 2150 # 2151 # Another variant would be write a temporary file on the same 2152 # filesystem, compare the files, and rename() the temporary file if it 2153 # differs, but it breaks stuff like write_config("/dev/null"), which is 2154 # used out there to force evaluation-related warnings to be generated. 2155 # This simple version is pretty failsafe and portable. 2156 2157 if not self._contents_eq(filename, contents): 2158 with self._open(filename, "w") as f: 2159 f.write(contents) 2160 2161 def _contents_eq(self, filename, contents): 2162 # Returns True if the contents of 'filename' is 'contents' (a string), 2163 # and False otherwise (including if 'filename' can't be opened/read) 2164 2165 try: 2166 with self._open(filename, "r") as f: 2167 # Robust re. things like encoding and line endings (mmap() 2168 # trickery isn't) 2169 return f.read(len(contents) + 1) == contents 2170 except IOError: 2171 # If the error here would prevent writing the file as well, we'll 2172 # notice it later 2173 return False 1961 2174 1962 2175 # … … 2010 2223 # hotspot during parsing. 2011 2224 # 2012 # Note: It might be possible to rewrite this to 'yield' tokens instead, 2013 # working across multiple lines. The 'option env' lookback thing below 2014 # complicates things though. 2225 # It might be possible to rewrite this to 'yield' tokens instead, 2226 # working across multiple lines. Lookback and compatibility with old 2227 # janky versions of the C tools complicate things though. 2228 2229 self._line = s # Used for error reporting 2015 2230 2016 2231 # Initial token on the line … … 2261 2476 return False 2262 2477 2263 2264 2478 # 2265 2479 # Preprocessor logic … … 2518 2732 2519 2733 return "" 2520 2521 2734 2522 2735 # … … 2623 2836 pattern = self._expect_str_and_eol() 2624 2837 2625 # Check if the pattern is absolute and avoid stripping srctree2626 # from it below in that case. We must do the check before2627 # join()'ing, as srctree might be an absolute path.2628 pattern_is_abs = isabs(pattern)2629 2630 2838 if t0 in _REL_SOURCE_TOKENS: 2631 2839 # Relative source 2632 2840 pattern = join(dirname(self._filename), pattern) 2633 2841 2634 # Sort the glob results to ensure a consistent ordering of 2635 # Kconfig symbols, which indirectly ensures a consistent 2636 # ordering in e.g. .config files 2637 filenames = sorted(iglob(join(self.srctree, pattern))) 2842 # - glob() doesn't support globbing relative to a directory, so 2843 # we need to prepend $srctree to 'pattern'. Use join() 2844 # instead of '+' so that an absolute path in 'pattern' is 2845 # preserved. 2846 # 2847 # - Sort the glob results to ensure a consistent ordering of 2848 # Kconfig symbols, which indirectly ensures a consistent 2849 # ordering in e.g. .config files 2850 filenames = sorted(iglob(join(self._srctree_prefix, pattern))) 2638 2851 2639 2852 if not filenames and t0 in _OBL_SOURCE_TOKENS: … … 2649 2862 2650 2863 for filename in filenames: 2651 self._enter_file( 2652 filename, 2653 # Unless an absolute path is passed to *source, strip 2654 # the $srctree prefix from the filename. That way it 2655 # appears without a $srctree prefix in 2656 # MenuNode.filename, which is nice e.g. when generating 2657 # documentation. 2658 filename if pattern_is_abs else 2659 relpath(filename, self.srctree)) 2660 2864 self._enter_file(filename) 2661 2865 prev = self._parse_block(None, parent, prev) 2662 2663 2866 self._leave_file() 2664 2867 2665 2868 elif t0 is end_token: 2666 # We have reached the end of the block. Terminate the final2667 # node andreturn it.2869 # Reached the end of the block. Terminate the final node and 2870 # return it. 2668 2871 2669 2872 if self._tokens[1] is not None: … … 2760 2963 elif t0 is _T_MAINMENU: 2761 2964 self.top_node.prompt = (self._expect_str_and_eol(), self.y) 2762 self.top_node.filename = self._filename2763 self.top_node.linenr = self._linenr2764 2965 2765 2966 else: … … 2954 3155 2955 3156 def _set_type(self, node, new_type): 2956 # Note: UNKNOWN == 0, whichis falsy3157 # UNKNOWN is falsy 2957 3158 if node.item.orig_type and node.item.orig_type is not new_type: 2958 3159 self._warn("{} defined with multiple types, {} will be used" … … 3227 3428 for choice in self.unique_choices: 3228 3429 choice._invalidate() 3229 3230 3430 3231 3431 # … … 3326 3526 cur = node.list 3327 3527 while cur: 3328 cur.dep = dep = self._make_and(cur.dep, basedep) 3329 3330 # Propagate dependencies to prompt 3331 if cur.prompt: 3332 cur.prompt = (cur.prompt[0], 3333 self._make_and(cur.prompt[1], dep)) 3528 dep = cur.dep = self._make_and(cur.dep, basedep) 3334 3529 3335 3530 if cur.item.__class__ in _SYMBOL_CHOICE: 3336 # Propagate 'visible if' dependencies to the prompt3531 # Propagate 'visible if' and dependencies to the prompt 3337 3532 if cur.prompt: 3338 3533 cur.prompt = (cur.prompt[0], 3339 self._make_and(cur.prompt[1], visible_if)) 3534 self._make_and( 3535 cur.prompt[1], 3536 self._make_and(visible_if, dep))) 3340 3537 3341 3538 # Propagate dependencies to defaults … … 3359 3556 for target, cond in cur.implies] 3360 3557 3558 elif cur.prompt: # Not a symbol/choice 3559 # Propagate dependencies to the prompt. 'visible if' is only 3560 # propagated to symbols/choices. 3561 cur.prompt = (cur.prompt[0], 3562 self._make_and(cur.prompt[1], dep)) 3361 3563 3362 3564 cur = cur.next … … 3394 3596 target.weak_rev_dep, 3395 3597 self._make_and(sym, cond)) 3396 3397 3598 3398 3599 # … … 3571 3772 # deprecated on Python 3, so play it future-safe. 3572 3773 # 3573 # A simpler solution would be to use io.open(), which defaults to3574 # universal newlines on both Python 2 and 3 (and is an alias for3575 # open() on Python 3), but it's appreciably slower on Python 2:3774 # io.open() defaults to universal newlines on Python 2 (and is an 3775 # alias for open() on Python 3), but it returns 'unicode' strings and 3776 # slows things down: 3576 3777 # 3577 3778 # Parsing x86 Kconfigs on Python 2 … … 3637 3838 3638 3839 msg = "undefined symbol {}:".format(sym.name) 3639 3640 3840 for node in self.node_iter(): 3641 3841 if sym in node.referenced: 3642 3842 msg += "\n\n- Referenced at {}:{}:\n\n{}" \ 3643 3843 .format(node.filename, node.linenr, node) 3644 3645 3844 self._warn(msg) 3646 3845 … … 3648 3847 # For printing general warnings 3649 3848 3650 if self._warnings_enabled: 3651 msg = "warning: " + msg 3652 if filename is not None: 3653 msg = "{}:{}: {}".format(filename, linenr, msg) 3654 3655 self.warnings.append(msg) 3656 if self._warn_to_stderr: 3657 sys.stderr.write(msg + "\n") 3658 3659 def _warn_override(self, msg, filename, linenr): 3660 # See the class documentation 3661 3662 if self._warn_for_override: 3663 self._warn(msg, filename, linenr) 3664 3665 def _warn_redun_assign(self, msg, filename, linenr): 3666 # See the class documentation 3667 3668 if self._warn_for_redun_assign: 3669 self._warn(msg, filename, linenr) 3849 if not self.warn: 3850 return 3851 3852 msg = "warning: " + msg 3853 if filename is not None: 3854 msg = "{}:{}: {}".format(filename, linenr, msg) 3855 3856 self.warnings.append(msg) 3857 if self.warn_to_stderr: 3858 sys.stderr.write(msg + "\n") 3670 3859 3671 3860 … … 3829 4018 List of (low, high, cond) tuples for the symbol's 'range' properties. For 3830 4019 example, 'range 1 2 if A' is represented as (1, 2, A). If there is no 3831 condition, 'cond' is self. config.y.4020 condition, 'cond' is self.kconfig.y. 3832 4021 3833 4022 Note that 'depends on' and parent dependencies are propagated to 'range' … … 3850 4039 3851 4040 direct_dep: 3852 The 'depends on' dependencies. If a symbol is defined in multiple 3853 locations, the dependencies at each location are ORed together. 3854 3855 Internally, this is used to implement 'imply', which only applies if the 3856 implied symbol has expr_value(self.direct_dep) != 0. 'depends on' and 3857 parent dependencies are automatically propagated to the conditions of 3858 properties, so normally it's redundant to check the direct dependencies. 4041 The direct ('depends on') dependencies for the symbol, or self.kconfig.y 4042 if there are no direct dependencies. 4043 4044 This attribute includes any dependencies from surrounding menus and if's. 4045 Those get propagated to the direct dependencies, and the resulting direct 4046 dependencies in turn get propagated to the conditions of all properties. 4047 4048 If the symbol is defined in multiple locations, the dependencies from the 4049 different locations get ORed together. 3859 4050 3860 4051 referenced: … … 3862 4053 property conditions of the symbol. 3863 4054 3864 Also includes dependencies inherited from surrounding menus and if's. 4055 Also includes dependencies from surrounding menus and if's, because those 4056 get propagated to the symbol (see the 'Intro to symbol values' section in 4057 the module docstring). 4058 3865 4059 Choices appear in the dependencies of choice symbols. 4060 4061 For the following definitions, only B and not C appears in A's 4062 'referenced'. To get transitive references, you'll have to recursively 4063 expand 'references' until no new items appear. 4064 4065 config A 4066 bool 4067 depends on B 4068 4069 config B 4070 bool 4071 depends on C 4072 4073 config C 4074 bool 4075 4076 See the Symbol.direct_dep attribute if you're only interested in the 4077 direct dependencies of the symbol (its 'depends on'). You can extract the 4078 symbols in it with the global expr_items() function. 3866 4079 3867 4080 env_var: … … 4179 4392 See the class documentation. 4180 4393 """ 4181 # Note: _write_to_conf is determined when the value is calculated. This4182 # is ahidden function call due to property magic.4394 # _write_to_conf is determined when the value is calculated. This is a 4395 # hidden function call due to property magic. 4183 4396 val = self.str_value 4184 4397 if not self._write_to_conf: … … 4287 4500 def unset_value(self): 4288 4501 """ 4289 Re sets the user value of the symbol, as if the symbol had never gotten4290 a user value via Kconfig.load_config() or Symbol.set_value().4502 Removes any user value from the symbol, as if the symbol had never 4503 gotten a user value via Kconfig.load_config() or Symbol.set_value(). 4291 4504 """ 4292 4505 if self.user_value is not None: … … 4359 4572 def __str__(self): 4360 4573 """ 4361 Returns a string representation of the symbol when it is printed, 4362 matching the Kconfig format, with parent dependencies propagated. 4574 Returns a string representation of the symbol when it is printed. 4575 Matches the Kconfig format, with any parent dependencies propagated to 4576 the 'depends on' condition. 4363 4577 4364 4578 The string is constructed by joining the strings returned by … … 4527 4741 return 4528 4742 4529 if self.kconfig._warn_ for_no_prompt:4743 if self.kconfig._warn_no_prompt: 4530 4744 self.kconfig._warn(_name_and_loc(self) + " has no prompt, meaning " 4531 4745 "user values have no effect on it") … … 4722 4936 List of (symbol, cond) tuples for the choice's 'defaults' properties. For 4723 4937 example, 'default A if B && C' is represented as (A, (AND, B, C)). If 4724 there is no condition, 'cond' is self. config.y.4938 there is no condition, 'cond' is self.kconfig.y. 4725 4939 4726 4940 Note that 'depends on' and parent dependencies are propagated to … … 4734 4948 conditions of the choice. 4735 4949 4736 Also includes dependencies inherited from surrounding menus and if's. 4950 Also includes dependencies from surrounding menus and if's, because those 4951 get propagated to the choice (see the 'Intro to symbol values' section in 4952 the module docstring). 4737 4953 4738 4954 is_optional: … … 4933 5149 def __str__(self): 4934 5150 """ 4935 Returns a string representation of the choice when it is printed, 4936 matching the Kconfig format (though without the contained choice 4937 symbols). 5151 Returns a string representation of the choice when it is printed. 5152 Matches the Kconfig format (though without the contained choice 5153 symbols), with any parent dependencies propagated to the 'depends on' 5154 condition. 4938 5155 4939 5156 The returned string does not end in a newline. … … 5114 5331 Like MenuNode.defaults, for ranges. 5115 5332 5333 orig_prompt: 5334 orig_defaults: 5335 orig_selects: 5336 orig_implies: 5337 orig_ranges: 5338 These work the like the corresponding attributes without orig_*, but omit 5339 any dependencies propagated from 'depends on' and surrounding 'if's (the 5340 direct dependencies, stored in MenuNode.dep). 5341 5342 One use for this is generating less cluttered documentation, by only 5343 showing the direct dependencies in one place. 5344 5116 5345 help: 5117 5346 The help text for the menu node for Symbols and Choices. None if there is … … 5125 5354 5126 5355 dep: 5127 The 'depends on' dependencies for the menu node, or self.kconfig.y if 5128 there are no dependencies. Parent dependencies are propagated to this 5129 attribute, and this attribute is then in turn propagated to the 5130 properties of symbols and choices. 5356 The direct ('depends on') dependencies for the menu node, or 5357 self.kconfig.y if there are no direct dependencies. 5358 5359 This attribute includes any dependencies from surrounding menus and if's. 5360 Those get propagated to the direct dependencies, and the resulting direct 5361 dependencies in turn get propagated to the conditions of all properties. 5131 5362 5132 5363 If a symbol or choice is defined in multiple locations, only the … … 5211 5442 5212 5443 @property 5444 def orig_prompt(self): 5445 """ 5446 See the class documentation. 5447 """ 5448 if not self.prompt: 5449 return None 5450 return (self.prompt[0], self._strip_dep(self.prompt[1])) 5451 5452 @property 5453 def orig_defaults(self): 5454 """ 5455 See the class documentation. 5456 """ 5457 return [(default, self._strip_dep(cond)) 5458 for default, cond in self.defaults] 5459 5460 @property 5461 def orig_selects(self): 5462 """ 5463 See the class documentation. 5464 """ 5465 return [(select, self._strip_dep(cond)) 5466 for select, cond in self.selects] 5467 5468 @property 5469 def orig_implies(self): 5470 """ 5471 See the class documentation. 5472 """ 5473 return [(imply, self._strip_dep(cond)) 5474 for imply, cond in self.implies] 5475 5476 @property 5477 def orig_ranges(self): 5478 """ 5479 See the class documentation. 5480 """ 5481 return [(low, high, self._strip_dep(cond)) 5482 for low, high, cond in self.ranges] 5483 5484 @property 5213 5485 def referenced(self): 5214 5486 """ … … 5295 5567 def __str__(self): 5296 5568 """ 5297 Returns a string representation of the menu node, matching the Kconfig 5298 format. 5569 Returns a string representation of the menu node. Matches the Kconfig 5570 format, with any parent dependencies propagated to the 'depends on' 5571 condition. 5299 5572 5300 5573 The output could (almost) be fed back into a Kconfig parser to redefine … … 5350 5623 lines = ["choice " + sc.name if sc.name else "choice"] 5351 5624 5352 if sc.orig_type: # != UNKNOWN 5625 if sc.orig_type and not self.prompt: # sc.orig_type != UNKNOWN 5626 # If there's a prompt, we'll use the '<type> "prompt"' shorthand 5627 # instead 5353 5628 indent_add(TYPE_TO_STR[sc.orig_type]) 5354 5629 5355 5630 if self.prompt: 5356 indent_add_cond( 5357 'prompt "{}"'.format(escape(self.prompt[0])), 5358 self.prompt[1]) 5631 if sc.orig_type: 5632 prefix = TYPE_TO_STR[sc.orig_type] 5633 else: 5634 # Symbol defined without a type (which generates a warning) 5635 prefix = "prompt" 5636 5637 indent_add_cond(prefix + ' "{}"'.format(escape(self.prompt[0])), 5638 self.orig_prompt[1]) 5359 5639 5360 5640 if sc.__class__ is Symbol: … … 5371 5651 indent_add("option modules") 5372 5652 5373 for low, high, cond in self. ranges:5653 for low, high, cond in self.orig_ranges: 5374 5654 indent_add_cond( 5375 5655 "range {} {}".format(sc_expr_str_fn(low), … … 5377 5657 cond) 5378 5658 5379 for default, cond in self. defaults:5659 for default, cond in self.orig_defaults: 5380 5660 indent_add_cond("default " + expr_str(default, sc_expr_str_fn), 5381 5661 cond) … … 5385 5665 5386 5666 if sc.__class__ is Symbol: 5387 for select, cond in self. selects:5667 for select, cond in self.orig_selects: 5388 5668 indent_add_cond("select " + sc_expr_str_fn(select), cond) 5389 5669 5390 for imply, cond in self. implies:5670 for imply, cond in self.orig_implies: 5391 5671 indent_add_cond("imply " + sc_expr_str_fn(imply), cond) 5392 5672 … … 5401 5681 return "\n".join(lines) 5402 5682 5683 def _strip_dep(self, expr): 5684 # Helper function for removing MenuNode.dep from 'expr'. Uses two 5685 # pieces of internal knowledge: (1) Expressions are reused rather than 5686 # copied, and (2) the direct dependencies always appear at the end. 5687 5688 # ... if dep -> ... if y 5689 if self.dep is expr: 5690 return self.kconfig.y 5691 5692 # (AND, X, dep) -> X 5693 if expr.__class__ is tuple and expr[0] is AND and expr[2] is self.dep: 5694 return expr[1] 5695 5696 return expr 5697 5403 5698 5404 5699 class Variable(object): … … 5419 5714 KconfigError if the expansion seems to be stuck in a loop. 5420 5715 5421 Note: Accessing this field is the same as calling expanded_value_w_args()5422 with no arguments. I hadn't considered function arguments when adding it.5423 Itis retained for backwards compatibility though.5716 Accessing this field is the same as calling expanded_value_w_args() with 5717 no arguments. I hadn't considered function arguments when adding it. It 5718 is retained for backwards compatibility though. 5424 5719 5425 5720 is_recursive: … … 5458 5753 5459 5754 class KconfigError(Exception): 5460 "Exception raised for Kconfig-related errors" 5755 """ 5756 Exception raised for Kconfig-related errors. 5757 5758 KconfigError and KconfigSyntaxError are the same class. The 5759 KconfigSyntaxError alias is only maintained for backwards compatibility. 5760 """ 5461 5761 5462 5762 KconfigSyntaxError = KconfigError # Backwards compatibility … … 5553 5853 """ 5554 5854 if sc.__class__ is Symbol: 5555 return '"{}"'.format(escape(sc.name)) if sc.is_constant else sc.name 5855 if sc.is_constant and sc.name not in ("n", "m", "y"): 5856 return '"{}"'.format(escape(sc.name)) 5857 return sc.name 5556 5858 5557 5859 # Choice … … 5721 6023 .config file to load/save) if it is set, and ".config" otherwise. 5722 6024 5723 Note: Calling load_config() with filename=None might give the behavior you5724 w ant, without having to use this function.6025 Calling load_config() with filename=None might give the behavior you want, 6026 without having to use this function. 5725 6027 """ 5726 6028 return os.environ.get("KCONFIG_CONFIG", ".config") … … 5734 6036 5735 6037 Disables warnings for duplicated assignments within configuration files for 5736 the duration of the call ( disable_override_warnings() +5737 disable_redun_warnings()), and enables themat the end. The6038 the duration of the call (kconf.warn_assign_override/warn_assign_redun = False), 6039 and restores the previous warning settings at the end. The 5738 6040 KCONFIG_ALLCONFIG configuration file is expected to override symbols. 5739 6041 … … 5749 6051 "allno.config", etc. 5750 6052 """ 6053 allconfig = os.environ.get("KCONFIG_ALLCONFIG") 6054 if allconfig is None: 6055 return 6056 5751 6057 def std_msg(e): 5752 6058 # "Upcasts" a _KconfigIOError to an IOError, removing the custom … … 5754 6060 return IOError(e.errno, e.strerror, e.filename) 5755 6061 5756 kconf.disable_override_warnings() 5757 kconf.disable_redun_warnings() 5758 5759 allconfig = os.environ.get("KCONFIG_ALLCONFIG") 5760 if allconfig is not None: 5761 if allconfig in ("", "1"): 6062 old_warn_assign_override = kconf.warn_assign_override 6063 old_warn_assign_redun = kconf.warn_assign_redun 6064 kconf.warn_assign_override = kconf.warn_assign_redun = False 6065 6066 if allconfig in ("", "1"): 6067 try: 6068 print(kconf.load_config(filename, False)) 6069 except IOError as e1: 5762 6070 try: 5763 kconf.load_config(filename, False) 5764 except IOError as e1: 5765 try: 5766 kconf.load_config("all.config", False) 5767 except IOError as e2: 5768 sys.exit("error: KCONFIG_ALLCONFIG is set, but neither {} " 5769 "nor all.config could be opened: {}, {}" 5770 .format(filename, std_msg(e1), std_msg(e2))) 5771 else: 5772 try: 5773 kconf.load_config(allconfig, False) 5774 except IOError as e: 5775 sys.exit("error: KCONFIG_ALLCONFIG is set to '{}', which " 5776 "could not be opened: {}" 5777 .format(allconfig, std_msg(e))) 5778 5779 # API wart: It would be nice if there was a way to query and/or push/pop 5780 # warning settings 5781 kconf.enable_override_warnings() 5782 kconf.enable_redun_warnings() 6071 print(kconf.load_config("all.config", False)) 6072 except IOError as e2: 6073 sys.exit("error: KCONFIG_ALLCONFIG is set, but neither {} " 6074 "nor all.config could be opened: {}, {}" 6075 .format(filename, std_msg(e1), std_msg(e2))) 6076 else: 6077 try: 6078 print(kconf.load_config(allconfig, False)) 6079 except IOError as e: 6080 sys.exit("error: KCONFIG_ALLCONFIG is set to '{}', which " 6081 "could not be opened: {}" 6082 .format(allconfig, std_msg(e))) 6083 6084 kconf.warn_assign_override = old_warn_assign_override 6085 kconf.warn_assign_redun = old_warn_assign_redun 5783 6086 5784 6087 … … 5880 6183 5881 6184 5882 def _touch_dep_file( sym_name):6185 def _touch_dep_file(path, sym_name): 5883 6186 # If sym_name is MY_SYM_NAME, touches my/sym/name.h. See the sync_deps() 5884 6187 # docstring. 5885 6188 5886 sym_path = sym_name.lower().replace("_", os.sep) + ".h"6189 sym_path = path + os.sep + sym_name.lower().replace("_", os.sep) + ".h" 5887 6190 sym_path_dir = dirname(sym_path) 5888 if sym_path_dir andnot exists(sym_path_dir):6191 if not exists(sym_path_dir): 5889 6192 os.makedirs(sym_path_dir, 0o755) 5890 6193 … … 5897 6200 # See write_config() 5898 6201 5899 dirname, basename = split(path) 5900 backup = join(dirname, 5901 basename + ".old" if basename.startswith(".") 5902 else "." + basename + ".old") 5903 5904 # os.replace() would be nice here, but it's Python 3 (3.3+) only 6202 def copy(src, dst): 6203 # Import as needed, to save some startup time 6204 import shutil 6205 shutil.copyfile(src, dst) 6206 6207 if islink(path): 6208 # Preserve symlinks 6209 copy_fn = copy 6210 elif hasattr(os, "replace"): 6211 # Python 3 (3.3+) only. Best choice when available, because it 6212 # removes <filename>.old on both *nix and Windows. 6213 copy_fn = os.replace 6214 elif os.name == "posix": 6215 # Removes <filename>.old on POSIX systems 6216 copy_fn = os.rename 6217 else: 6218 # Fall back on copying 6219 copy_fn = copy 6220 5905 6221 try: 5906 # Use copyfile() if 'path' is a symlink. The intention is probably to 5907 # overwrite the target in that case. 5908 if os.name == "posix" and not islink(path): 5909 # Will remove .<filename>.old if it already exists on POSIX 5910 # systems 5911 os.rename(path, backup) 5912 else: 5913 # Only import as needed, to save some startup time 5914 import shutil 5915 shutil.copyfile(path, backup) 5916 except: 5917 # Ignore errors from 'filename' missing as well as other errors. The 5918 # backup file is more of a nice-to-have, and not worth erroring out 5919 # over e.g. if .<filename>.old happens to be a directory. 6222 copy_fn(path, path + ".old") 6223 except Exception: 6224 # Ignore errors from 'path' missing as well as other errors. 6225 # <filename>.old file is usually more of a nice-to-have, and not worth 6226 # erroring out over e.g. if <filename>.old happens to be a directory or 6227 # <filename> is something like /dev/null. 5920 6228 pass 5921 5922 5923 def _decoding_error(e, filename, macro_linenr=None):5924 # Gives the filename and context for UnicodeDecodeError's, which are a pain5925 # to debug otherwise. 'e' is the UnicodeDecodeError object.5926 #5927 # If the decoding error is for the output of a $(shell,...) command,5928 # macro_linenr holds the line number where it was run (the exact line5929 # number isn't available for decoding errors in files).5930 5931 raise KconfigError(5932 "\n"5933 "Malformed {} in {}\n"5934 "Context: {}\n"5935 "Problematic data: {}\n"5936 "Reason: {}".format(5937 e.encoding,5938 "'{}'".format(filename) if macro_linenr is None else5939 "output from macro at {}:{}".format(filename, macro_linenr),5940 e.object[max(e.start - 40, 0):e.end + 40],5941 e.object[e.start:e.end],5942 e.reason))5943 6229 5944 6230 … … 5995 6281 # at node2.dep. 5996 6282 5997 # If node2 has no prompt, use its menu node dependencies instead5998 6283 return _expr_depends_on(node2.prompt[1] if node2.prompt else node2.dep, 5999 6284 node1.item) … … 6241 6526 6242 6527 6528 def _decoding_error(e, filename, macro_linenr=None): 6529 # Gives the filename and context for UnicodeDecodeError's, which are a pain 6530 # to debug otherwise. 'e' is the UnicodeDecodeError object. 6531 # 6532 # If the decoding error is for the output of a $(shell,...) command, 6533 # macro_linenr holds the line number where it was run (the exact line 6534 # number isn't available for decoding errors in files). 6535 6536 raise KconfigError( 6537 "\n" 6538 "Malformed {} in {}\n" 6539 "Context: {}\n" 6540 "Problematic data: {}\n" 6541 "Reason: {}".format( 6542 e.encoding, 6543 "'{}'".format(filename) if macro_linenr is None else 6544 "output from macro at {}:{}".format(filename, macro_linenr), 6545 e.object[max(e.start - 40, 0):e.end + 40], 6546 e.object[e.start:e.end], 6547 e.reason)) 6548 6549 6550 def _warn_verbose_deprecated(fn_name): 6551 sys.stderr.write( 6552 "Deprecation warning: {0}()'s 'verbose' argument has no effect. Since " 6553 "Kconfiglib 12.0.0, the message is returned from {0}() instead, " 6554 "and is always generated. Do e.g. print(kconf.{0}()) if you want to " 6555 "want to show a message like \"Loaded configuration '.config'\" on " 6556 "stdout. The old API required ugly hacks to reuse messages in " 6557 "configuration interfaces.\n".format(fn_name)) 6558 6559 6243 6560 # Predefined preprocessor functions 6244 6561 … … 6333 6650 _UNAME_RELEASE = platform.uname()[2] 6334 6651 6335 # Note: The token and type constants below are safe to test with 'is', which is6336 # a bitfaster (~30% faster on my machine, and a few % faster for total parsing6652 # The token and type constants below are safe to test with 'is', which is a bit 6653 # faster (~30% faster on my machine, and a few % faster for total parsing 6337 6654 # time), even without assuming Python's small integer optimization (which 6338 6655 # caches small integer objects). The constants end up pointing to unique … … 6632 6949 # '$' is included to detect preprocessor variable assignments with macro 6633 6950 # expansions in the left-hand side. 6634 _command_match = _re_match(r"\s*([ $A-Za-z0-9_-]+)\s*")6951 _command_match = _re_match(r"\s*([A-Za-z0-9_$-]+)\s*") 6635 6952 6636 6953 # An identifier/keyword after the first token. Also eats trailing whitespace. 6637 6954 # '$' is included to detect identifiers containing macro expansions. 6638 _id_keyword_match = _re_match(r"([ $A-Za-z0-9_/.-]+)\s*")6955 _id_keyword_match = _re_match(r"([A-Za-z0-9_$/.-]+)\s*") 6639 6956 6640 6957 # A fragment in the left-hand side of a preprocessor variable assignment. These
Note:
See TracChangeset
for help on using the changeset viewer.