2 # SPDX-License-Identifier: ISC
4 # Author: Ulf Magnusson
5 # https://github.com/ulfalizer/Kconfiglib
7 # This is Kconfiglib, a Python library for scripting, debugging, and extracting
8 # information from Kconfig-based configuration systems. To view the
13 # or, if you prefer HTML,
15 # $ pydoc -w kconfiglib
17 # The examples/ subdirectory contains examples, to be run with e.g.
19 # $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
21 # Look in testsuite.py for the test suite.
24 Kconfiglib is a Python library for scripting and extracting information from
25 Kconfig-based configuration systems. Features include the following:
27 - Symbol values and properties can be looked up and values assigned
29 - .config files can be read and written.
30 - Expressions can be evaluated in the context of a Kconfig configuration.
31 - Relations between symbols can be quickly determined, such as finding all
32 symbols that reference a particular symbol.
33 - Highly compatible with the scripts/kconfig/*conf utilities. The test suite
34 automatically compares outputs between Kconfiglib and the C implementation
35 for a large number of cases.
37 For the Linux kernel, scripts are run using
39 $ make scriptconfig SCRIPT=<path to script> [SCRIPT_ARG=<arg>]
41 Running scripts via the 'scriptconfig' target ensures that required environment
42 variables (SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly.
43 Alternative architectures can be specified like for other 'make *config'
46 $ make scriptconfig ARCH=mips SCRIPT=<path to script> [SCRIPT_ARG=<arg>]
48 The script will receive the name of the Kconfig file to load in sys.argv[1].
49 (As of Linux 3.7.0-rc8 this is always "Kconfig" from the kernel top-level
50 directory.) If an argument is provided with SCRIPT_ARG, it will appear in
53 To get an interactive Python prompt with Kconfiglib preloaded and a Config
54 object 'c' created, use
56 $ make iscriptconfig [ARCH=<architecture>]
58 Kconfiglib requires Python 2. For (i)scriptconfig the command to run the Python
59 interpreter can be passed in the environment variable PYTHONCMD (defaults to
60 'python'; PyPy works too and is a bit faster).
62 Look in the examples/ subdirectory for examples, which can be run with e.g.
64 $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
68 $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG="kernel"
70 Look in testsuite.py for the test suite.
72 Credits: Written by Ulf "Ulfalizer" Magnusson
74 Send bug reports, suggestions and other feedback to kconfiglib@gmail.com .
75 Don't wrestle with internal APIs. Tell me what you need and I might add it in a
76 safe way as a client API instead."""
78 # If you have Psyco installed (32-bit installations, Python <= 2.6 only),
79 # setting this to True (right here, not at runtime) might give a nice speedup.
80 # (22% faster for parsing arch/x86/Kconfig and 58% faster for evaluating all
81 # symbols in it without a .config on my Core Duo.)
91 """Represents a Kconfig configuration, e.g. for i386 or ARM. This is the
92 set of symbols and other items appearing in the configuration together with
93 their values. Creating any number of Config objects -- including for
94 different architectures -- is safe; Kconfiglib has no global state."""
101 filename = "Kconfig",
102 base_dir = "$srctree",
103 print_warnings = True,
104 print_undef_assign = False):
105 """Creates a new Config object, representing a Kconfig configuration.
106 Raises Kconfig_Syntax_Error on syntax errors.
108 filename (default: "Kconfig") -- The base Kconfig file of the
109 configuration. For the Linux kernel, this should usually be be
110 "Kconfig" from the top-level directory, as environment
111 variables will make sure the right Kconfig is included from
112 there (usually arch/<architecture>/Kconfig). If you are using
113 kconfiglib via 'make scriptconfig' the filename of the
114 correct Kconfig will be in sys.argv[1].
116 base_dir (default: "$srctree") -- The base directory relative to which
117 'source' statements within Kconfig files will work. For the
118 Linux kernel this should be the top-level directory of the
119 kernel tree. $-references to environment variables will be
122 The environment variable 'srctree' is set by the Linux makefiles
123 to the top-level kernel directory. A default of "." would not
124 work if an alternative build directory is used.
126 print_warnings (default: True) -- Set to True if warnings related to
127 this configuration should be printed to stderr. This can
128 be changed later with Config.set_print_warnings(). It is
129 provided as a constructor argument since warnings might
130 be generated during parsing.
132 print_undef_assign (default: False) -- Set to True if informational
133 messages related to assignments to undefined symbols
134 should be printed to stderr for this configuration.
135 Can be changed later with
136 Config.set_print_undef_assign()."""
138 # The set of all symbols, indexed by name (a string)
141 # The set of all defined symbols in the configuration in the order they
142 # appear in the Kconfig files. This excludes the special symbols n, m,
143 # and y as well as symbols that are referenced but never defined.
144 self.kconfig_syms = []
146 # The set of all named choices (yes, choices can have names), indexed
148 self.named_choices = {}
150 def register_special_symbol(type, name, value):
152 sym.is_special_ = True
153 sym.is_defined_ = True
157 sym.cached_value = value
158 self.syms[name] = sym
161 # The special symbols n, m and y, used as shorthand for "n", "m" and
163 self.n = register_special_symbol(TRISTATE, "n", "n")
164 self.m = register_special_symbol(TRISTATE, "m", "m")
165 self.y = register_special_symbol(TRISTATE, "y", "y")
167 # DEFCONFIG_LIST uses this
168 register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
170 # The symbol with "option defconfig_list" set, containing a list of
171 # default .config files
172 self.defconfig_sym = None
174 # See Symbol.get_(src)arch()
175 self.arch = os.environ.get("ARCH")
176 self.srcarch = os.environ.get("SRCARCH")
178 # See Config.__init__(). We need this for get_defconfig_filename().
179 self.srctree = os.environ.get("srctree")
180 if self.srctree is None:
183 self.filename = filename
184 self.base_dir = _strip_trailing_slash(os.path.expandvars(base_dir))
186 # The 'mainmenu' text
187 self.mainmenu_text = None
189 # The filename of the most recently loaded .config file
190 self.config_filename = None
192 # The textual header of the most recently loaded .config, uncommented
193 self.config_header = None
195 self.print_warnings = print_warnings
196 self.print_undef_assign = print_undef_assign
198 # Lists containing all choices, menus and comments in the configuration
204 # For parsing routines that stop when finding a line belonging to a
205 # different construct, these holds that line and the tokenized version
206 # of that line. The purpose is to avoid having to re-tokenize the line,
207 # which is inefficient and causes problems when recording references to
210 self.end_line_tokens = None
212 # See the comment in _parse_expr().
213 self.parse_expr_cur_sym_or_choice = None
214 self.parse_expr_line = None
215 self.parse_expr_filename = None
216 self.parse_expr_linenr = None
217 self.parse_expr_transform_m = None
219 # Parse the Kconfig files
220 self.top_block = self._parse_file(filename, None, None, None)
222 # Build Symbol.dep for all symbols
225 def load_config(self, filename, replace = True):
226 """Loads symbol values from a file in the familiar .config format.
227 Equivalent to calling Symbol.set_user_value() to set each of the
230 filename -- The .config file to load. $-references to environment
231 variables will be expanded. For scripts to work even
232 when an alternative build directory is used with the
233 Linux kernel, you need to refer to the top-level kernel
234 directory with "$srctree".
236 replace (default: True) -- True if the configuration should replace
237 the old configuration; False if it should add to it."""
239 def warn_override(filename, linenr, name, old_user_val, new_user_val):
240 self._warn("overriding the value of {0}. "
241 'Old value: "{1}", new value: "{2}".'
242 .format(name, old_user_val, new_user_val),
246 filename = os.path.expandvars(filename)
248 # Put this first so that a missing file doesn't screw up our state
249 line_feeder = _FileFeed(_get_lines(filename), filename)
251 self.config_filename = filename
253 # Invalidate everything. This is usually faster than finding the
254 # minimal set of symbols that needs to be invalidated, as nearly all
255 # symbols will tend to be affected anyway.
257 self.unset_user_values()
259 self._invalidate_all()
263 self.config_header = None
265 def is_header_line(line):
266 return line.startswith("#") and \
267 not unset_re.match(line)
269 first_line = line_feeder.get_next()
271 if first_line is None:
274 if not is_header_line(first_line):
275 line_feeder.go_back()
277 self.config_header = first_line[1:]
279 # Read remaining header lines
281 line = line_feeder.get_next()
286 if not is_header_line(line):
287 line_feeder.go_back()
290 self.config_header += line[1:]
292 # Remove trailing newline
293 if self.config_header.endswith("\n"):
294 self.config_header = self.config_header[:-1]
298 filename = line_feeder.get_filename()
301 line = line_feeder.get_next()
305 linenr = line_feeder.get_linenr()
309 set_re_match = set_re.match(line)
311 name, val = set_re_match.groups()
312 # The unescaping producedure below should be safe since " can
313 # only appear as \" inside the string
314 val = _strip_quotes(val, line, filename, linenr)\
315 .replace('\\"', '"').replace("\\\\", "\\")
316 if name in self.syms:
317 sym = self.syms[name]
319 old_user_val = sym.user_val
320 if old_user_val is not None:
321 warn_override(filename, linenr, name, old_user_val, val)
323 if sym.is_choice_symbol_:
324 user_mode = sym.parent.user_mode
325 if user_mode is not None and user_mode != val:
326 self._warn("assignment to {0} changes mode of containing "
327 'choice from "{1}" to "{2}".'
328 .format(name, val, user_mode),
332 sym._set_user_value_no_invalidate(val, True)
335 self._undef_assign('attempt to assign the value "{0}" to the '
336 "undefined symbol {1}."
342 unset_re_match = unset_re.match(line)
344 name = unset_re_match.group(1)
345 if name in self.syms:
346 sym = self.syms[name]
348 old_user_val = sym.user_val
349 if old_user_val is not None:
350 warn_override(filename, linenr, name, old_user_val, "n")
352 sym._set_user_value_no_invalidate("n", True)
354 def write_config(self, filename, header = None):
355 """Writes out symbol values in the familiar .config format.
357 filename -- The filename under which to save the configuration.
359 header (default: None) -- A textual header that will appear at the
360 beginning of the file, with each line commented out
361 automatically. None means no header."""
363 # already_written is set when _make_conf() is called on a symbol, so
364 # that symbols defined in multiple locations only get one entry in the
365 # .config. We need to reset it prior to writing out a new .config.
366 for sym in self.syms.itervalues():
367 sym.already_written = False
369 with open(filename, "w") as f:
371 if header is not None:
372 f.write(_comment(header))
375 # Write configuration.
376 # (You'd think passing a list around to all the nodes and appending
377 # to it to avoid copying would be faster, but it's actually a lot
378 # slower with PyPy, and about as fast with Python. Passing the file
379 # around is slower too.)
380 f.write("\n".join(self.top_block._make_conf()))
383 def get_kconfig_filename(self):
384 """Returns the name of the (base) kconfig file this configuration was
389 """Returns the value the environment variable ARCH had at the time the
390 Config instance was created, or None if ARCH was not set. For the
391 kernel, this corresponds to the architecture being built for, with
392 values such as "i386" or "mips"."""
395 def get_srcarch(self):
396 """Returns the value the environment variable SRCARCH had at the time
397 the Config instance was created, or None if SRCARCH was not set. For
398 the kernel, this corresponds to the arch/ subdirectory containing
399 architecture-specific source code."""
402 def get_srctree(self):
403 """Returns the value the environment variable srctree had at the time
404 the Config instance was created, or None if srctree was not defined.
405 This variable points to the source directory and is used when building
406 in a separate directory."""
409 def get_config_filename(self):
410 """Returns the name of the most recently loaded configuration file, or
411 None if no configuration has been loaded."""
412 return self.config_filename
414 def get_mainmenu_text(self):
415 """Returns the text of the 'mainmenu' statement (with $-references to
416 symbols replaced by symbol values), or None if the configuration has no
417 'mainmenu' statement."""
418 return None if self.mainmenu_text is None else \
419 self._expand_sym_refs(self.mainmenu_text)
421 def get_defconfig_filename(self):
422 """Returns the name of the defconfig file, which is the first existing
423 file in the list given in a symbol having 'option defconfig_list' set.
424 $-references to symbols will be expanded ("$FOO bar" -> "foo bar" if
425 FOO has the value "foo"). Returns None in case of no defconfig file.
426 Setting 'option defconfig_list' on multiple symbols currently results
427 in undefined behavior.
429 If the environment variable 'srctree' was set when the Config was
430 created, get_defconfig_filename() will first look relative to that
431 directory before looking in the current directory; see
434 WARNING: A wart here is that scripts/kconfig/Makefile sometimes uses the
435 --defconfig=<defconfig> option when calling the C implementation of e.g.
436 'make defconfig'. This option overrides the 'option defconfig_list'
437 symbol, meaning the result from get_defconfig_filename() might not
438 match what 'make defconfig' would use. That probably ought to be worked
439 around somehow, so that this function always gives the "expected"
442 if self.defconfig_sym is None:
445 for (filename, cond_expr) in self.defconfig_sym.def_exprs:
446 if self._eval_expr(cond_expr) == "y":
447 filename = self._expand_sym_refs(filename)
449 # We first look in $srctree. os.path.join() won't work here as
450 # an absolute path in filename would override $srctree.
451 srctree_filename = os.path.normpath(self.srctree + "/" + filename)
452 if os.path.exists(srctree_filename):
453 return srctree_filename
455 if os.path.exists(filename):
460 def get_symbol(self, name):
461 """Returns the symbol with name 'name', or None if no such symbol
462 appears in the configuration. An alternative shorthand is conf[name],
463 where conf is a Config instance, though that will instead raise
464 KeyError if the symbol does not exist."""
465 return self.syms.get(name)
467 def get_top_level_items(self):
468 """Returns a list containing the items (symbols, menus, choice
469 statements and comments) at the top level of the configuration -- that
470 is, all items that do not appear within a menu or choice. The items
471 appear in the same order as within the configuration."""
472 return self.top_block.get_items()
474 def get_symbols(self, all_symbols = True):
475 """Returns a list of symbols from the configuration. An alternative for
476 iterating over all defined symbols (in the order of definition) is
481 which relies on Config implementing __iter__() and is equivalent to
483 for sym in config.get_symbols(False):
486 all_symbols (default: True) -- If True, all symbols - including special
487 and undefined symbols - will be included in the result, in
488 an undefined order. If False, only symbols actually defined
489 and not merely referred to in the configuration will be
490 included in the result, and will appear in the order that
491 they are defined within the Kconfig configuration files."""
492 return self.syms.values() if all_symbols else self.kconfig_syms
494 def get_choices(self):
495 """Returns a list containing all choice statements in the
496 configuration, in the order they appear in the Kconfig files."""
500 """Returns a list containing all menus in the configuration, in the
501 order they appear in the Kconfig files."""
504 def get_comments(self):
505 """Returns a list containing all comments in the configuration, in the
506 order they appear in the Kconfig files."""
510 """Returns the value of the expression 's' -- where 's' is represented
511 as a string -- in the context of the configuration. Raises
512 Kconfig_Syntax_Error if syntax errors are detected in 's'.
514 For example, if FOO and BAR are tristate symbols at least one of which
515 has the value "y", then config.eval("y && (FOO || BAR)") => "y"
517 This function always yields a tristate value. To get the value of
518 non-bool, non-tristate symbols, use Symbol.get_value().
520 The result of this function is consistent with how evaluation works for
521 conditional expressions in the configuration as well as in the C
522 implementation. "m" and m are rewritten as '"m" && MODULES' and 'm &&
523 MODULES', respectively, and a result of "m" will get promoted to "y" if
524 we're running without modules."""
525 return self._eval_expr(self._parse_expr(self._tokenize(s, True), # Feed
526 None, # Current symbol or choice
529 def get_config_header(self):
530 """Returns the (uncommented) textual header of the .config file most
531 recently loaded with load_config(). Returns None if no .config file has
532 been loaded or if the most recently loaded .config file has no header.
533 The header comprises all lines up to but not including the first line
536 1. Does not start with "#"
537 2. Has the form "# CONFIG_FOO is not set."
539 return self.config_header
541 def get_base_dir(self):
542 """Returns the base directory relative to which 'source' statements
543 will work, passed as an argument to Config.__init__()."""
546 def set_print_warnings(self, print_warnings):
547 """Determines whether warnings related to this configuration (for
548 things like attempting to assign illegal values to symbols with
549 Symbol.set_user_value()) should be printed to stderr.
551 print_warnings -- True if warnings should be
552 printed, otherwise False."""
553 self.print_warnings = print_warnings
555 def set_print_undef_assign(self, print_undef_assign):
556 """Determines whether informational messages related to assignments to
557 undefined symbols should be printed to stderr for this configuration.
559 print_undef_assign -- If True, such messages will be printed."""
560 self.print_undef_assign = print_undef_assign
562 def __getitem__(self, key):
563 """Returns the symbol with name 'name'. Raises KeyError if the symbol
564 does not appear in the configuration."""
565 return self.syms[key]
568 """Convenience function for iterating over the set of all defined
569 symbols in the configuration, used like
574 The iteration happens in the order of definition within the Kconfig
575 configuration files. Symbols only referred to but not defined will not
576 be included, nor will the special symbols n, m, and y. If you want to
577 include such symbols as well, see config.get_symbols()."""
578 return iter(self.kconfig_syms)
580 def unset_user_values(self):
581 """Resets the values of all symbols, as if Config.load_config() or
582 Symbol.set_user_value() had never been called."""
583 for sym in self.syms.itervalues():
584 sym._unset_user_value_no_recursive_invalidate()
587 """Returns a string containing various information about the Config."""
588 return _sep_lines("Configuration",
589 "File : " + self.filename,
590 "Base directory : " + self.base_dir,
591 "Value of $ARCH at creation time : " +
592 ("(not set)" if self.arch is None else self.arch),
593 "Value of $SRCARCH at creation time : " +
594 ("(not set)" if self.srcarch is None else self.srcarch),
595 "Source tree (derived from $srctree;",
596 "defaults to '.' if $srctree isn't set) : " + self.srctree,
597 "Most recently loaded .config : " +
598 ("(no .config loaded)" if self.config_filename is None else
599 self.config_filename),
600 "Print warnings : " +
601 bool_str[self.print_warnings],
602 "Print assignments to undefined symbols : " +
603 bool_str[self.print_undef_assign])
610 def _invalidate_all(self):
611 for sym in self.syms.itervalues():
619 """Returns a _Feed instance containing tokens derived from the string
620 's'. Registers any new symbols encountered (via _sym_lookup()).
622 (I experimented with a pure regular expression implementation, but it
623 came out slower, less readable, and wouldn't have been as flexible.)
625 for_eval -- True when parsing an expression for a call to
626 Config.eval(), in which case we should not treat the first
627 token specially nor register new symbols."""
629 if s == "" or s[0] == "#":
633 i = 0 # The current index in the string being tokenized
634 previous = None # The previous token seen
637 # The initial word on a line is parsed specially. Let
638 # command_chars = [A-Za-z0-9_]. Then
639 # - leading non-command_chars characters on the line are ignored, and
640 # - the first token consists the following one or more command_chars
642 # This is why things like "----help--" are accepted.
644 initial_token_match = initial_token_re.match(s)
645 if initial_token_match is None:
647 # The current index in the string being tokenized
648 i = initial_token_match.end()
650 keyword = keywords.get(initial_token_match.group(1))
652 # We expect a keyword as the first token
653 _tokenization_error(s, len(s), filename, linenr)
654 if keyword == T_HELP:
655 # Avoid junk after "help", e.g. "---", being registered as a
657 return _Feed([T_HELP])
661 # _tokenize() is a hotspot during parsing, and this speeds things up a
664 append = tokens.append
666 # Main tokenization loop. (Handles tokens past the first one.)
668 # Test for an identifier/keyword preceded by whitespace first; this
669 # is the most common case.
670 id_keyword_match = id_keyword_re.match(s, i)
672 # We have an identifier or keyword. The above also stripped any
674 name = id_keyword_match.group(1)
676 i = id_keyword_match.end()
679 keyword = keywords.get(name)
680 if keyword is not None:
682 # What would ordinarily be considered a name is treated as a
683 # string after certain tokens.
684 elif previous in string_lex:
687 # We're dealing with a symbol. _sym_lookup() will take care
688 # of allocating a new Symbol instance if it's the first
690 sym = self._sym_lookup(name, not for_eval)
692 if previous == T_CONFIG or previous == T_MENUCONFIG:
693 # If the previous token is T_(MENU)CONFIG
694 # ("(menu)config"), we're tokenizing the first line of
695 # a symbol definition, and should remember this as a
696 # location where the symbol is defined.
697 sym.def_locations.append((filename, linenr))
699 # Otherwise, it's a reference to the symbol
700 sym.ref_locations.append((filename, linenr))
705 # This restrips whitespace that could have been stripped in the
706 # regex above, but it's worth it since identifiers/keywords are
715 # String literal (constant symbol)
716 if c == '"' or c == "'":
720 # Slow path: This could probably be sped up, but it's a
721 # very unusual case anyway.
726 _tokenization_error(s, strlen, filename,
733 _tokenization_error(s, strlen, filename,
743 # Fast path: If the string contains no backslashes (almost
744 # always) we can simply look for the matching quote.
747 _tokenization_error(s, strlen, filename, linenr)
753 # Invalid characters are ignored
756 # Invalid characters are ignored
764 # Invalid characters are ignored
767 # Invalid characters are ignored
775 _tokenization_error(s, strlen, filename, linenr)
792 append(T_CLOSE_PAREN)
799 # Invalid characters are ignored
803 previous = tokens[-1]
811 # Expression grammar:
814 # <symbol> '=' <symbol>
815 # <symbol> '!=' <symbol>
821 def _parse_expr(self,
828 """Parse an expression from the tokens in 'feed' using a simple
829 top-down approach. The result has the form (<operator>, <list
830 containing parsed operands>).
832 feed -- _Feed instance containing the tokens for the expression.
834 cur_sym_or_choice -- The symbol or choice currently being parsed, or
835 None if we're not parsing a symbol or choice.
836 Used for recording references to symbols.
838 line -- The line containing the expression being parsed.
840 filename (default: None) -- The file containing the expression.
842 linenr (default: None) -- The line number containing the expression.
844 transform_m (default: False) -- Determines if 'm' should be rewritten to
845 'm && MODULES' -- see
846 parse_val_and_cond()."""
848 # Use instance variables to avoid having to pass these as arguments
849 # through the top-down parser in _parse_expr_2(), which is tedious and
850 # obfuscates the code. A profiler run shows no noticeable performance
852 self.parse_expr_cur_sym_or_choice = cur_sym_or_choice
853 self.parse_expr_line = line
854 self.parse_expr_filename = filename
855 self.parse_expr_linenr = linenr
856 self.parse_expr_transform_m = transform_m
858 return self._parse_expr_2(feed)
860 def _parse_expr_2(self, feed):
861 or_terms = [self._parse_or_term(feed)]
862 # Keep parsing additional terms while the lookahead is '||'
863 while feed.check(T_OR):
864 or_terms.append(self._parse_or_term(feed))
866 return or_terms[0] if len(or_terms) == 1 else (OR, or_terms)
868 def _parse_or_term(self, feed):
869 and_terms = [self._parse_factor(feed)]
870 # Keep parsing additional terms while the lookahead is '&&'
871 while feed.check(T_AND):
872 and_terms.append(self._parse_factor(feed))
874 return and_terms[0] if len(and_terms) == 1 else (AND, and_terms)
876 def _parse_factor(self, feed):
877 if feed.check(T_OPEN_PAREN):
878 expr_parse = self._parse_expr_2(feed)
880 if not feed.check(T_CLOSE_PAREN):
881 _parse_error(self.parse_expr_line,
882 "missing end parenthesis.",
883 self.parse_expr_filename,
884 self.parse_expr_linenr)
888 if feed.check(T_NOT):
889 return (NOT, self._parse_factor(feed))
891 sym_or_string = feed.get_next()
893 if not isinstance(sym_or_string, (Symbol, str)):
894 _parse_error(self.parse_expr_line,
895 "malformed expression.",
896 self.parse_expr_filename,
897 self.parse_expr_linenr)
899 if self.parse_expr_cur_sym_or_choice is not None and \
900 isinstance(sym_or_string, Symbol):
901 self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string)
903 next_token = feed.peek_next()
905 # For conditional expressions ('depends on <expr>', '... if <expr>',
906 # etc.), "m" and m are rewritten to "m" && MODULES.
907 if next_token != T_EQUAL and next_token != T_UNEQUAL:
908 if self.parse_expr_transform_m and (sym_or_string is self.m or
909 sym_or_string == "m"):
910 return (AND, ["m", self._sym_lookup("MODULES")])
913 relation = EQUAL if (feed.get_next() == T_EQUAL) else UNEQUAL
914 sym_or_string_2 = feed.get_next()
916 if self.parse_expr_cur_sym_or_choice is not None and \
917 isinstance(sym_or_string_2, Symbol):
918 self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string_2)
920 if sym_or_string is self.m:
923 if sym_or_string_2 is self.m:
924 sym_or_string_2 = "m"
926 return (relation, sym_or_string, sym_or_string_2)
928 def _parse_file(self, filename, parent, deps, visible_if_deps, res = None):
929 """Parse the Kconfig file 'filename'. The result is a _Block with all
930 items from the file. See _parse_block() for the meaning of the
932 line_feeder = _FileFeed(_get_lines(filename), filename)
933 return self._parse_block(line_feeder, None, parent, deps, visible_if_deps, res)
935 def _parse_block(self, line_feeder, end_marker, parent, deps,
936 visible_if_deps = None, res = None):
937 """Parses a block, which is the contents of either a file or an if,
938 menu, or choice statement. The result is a _Block with the items from
941 end_marker -- The token that ends the block, e.g. T_ENDIF ("endif") for
942 if's. None for files.
944 parent -- The enclosing menu, choice or if, or None if we're at the top
947 deps -- Dependencies from enclosing menus, choices and if's.
949 visible_if_deps (default: None) -- 'visible if' dependencies from
952 res (default: None) -- The _Block to add items to. If None, a new
953 _Block is created to hold the items."""
955 block = _Block() if res is None else res
957 filename = line_feeder.get_filename()
961 # Do we already have a tokenized line that we determined wasn't
962 # part of whatever we were parsing earlier? See comment in
964 if self.end_line is not None:
965 assert self.end_line_tokens is not None
966 tokens = self.end_line_tokens
970 linenr = line_feeder.get_linenr()
973 self.end_line_tokens = None
976 line = line_feeder.get_next()
978 if end_marker is not None:
979 raise Kconfig_Syntax_Error, (
980 "Unexpected end of file {0}."
981 .format(line_feeder.get_filename()))
984 linenr = line_feeder.get_linenr()
986 tokens = self._tokenize(line, False, filename, linenr)
988 if tokens.is_empty():
991 t0 = tokens.get_next()
993 # Have we reached the end of the block?
997 if t0 == T_CONFIG or t0 == T_MENUCONFIG:
998 # The tokenizer will automatically allocate a new Symbol object
999 # for any new names it encounters, so we don't need to worry
1001 sym = tokens.get_next()
1003 # Symbols defined in multiple places get the parent of their
1004 # first definition. However, for symbols whose parents are choice
1005 # statements, the choice statement takes precedence.
1006 if not sym.is_defined_ or isinstance(parent, Choice):
1009 sym.is_defined_ = True
1011 self.kconfig_syms.append(sym)
1014 self._parse_properties(line_feeder, sym, deps, visible_if_deps)
1018 self.menus.append(menu)
1020 menu.parent = parent
1021 menu.title = tokens.get_next()
1023 menu.filename = filename
1024 menu.linenr = linenr
1026 # Parse properties and contents
1027 self._parse_properties(line_feeder, menu, deps, visible_if_deps)
1028 menu.block = self._parse_block(line_feeder,
1032 _make_and(visible_if_deps,
1033 menu.visible_if_expr))
1035 block.add_item(menu)
1038 # If statements are treated as syntactic sugar for adding
1039 # dependencies to enclosed items and do not have an explicit
1040 # object representation.
1042 dep_expr = self._parse_expr(tokens, None, line, filename, linenr)
1043 self._parse_block(line_feeder,
1046 _make_and(dep_expr, deps),
1048 block) # Add items to the same block
1050 elif t0 == T_CHOICE:
1051 # We support named choices
1052 already_defined = False
1054 if len(tokens) > 1 and isinstance(tokens[1], str):
1056 already_defined = name in self.named_choices
1059 choice = self.named_choices[name]
1062 self.choices.append(choice)
1063 if name is not None:
1065 self.named_choices[name] = choice
1067 choice.config = self
1068 choice.parent = parent
1070 choice.def_locations.append((filename, linenr))
1072 # Parse properties and contents
1073 self._parse_properties(line_feeder, choice, deps, visible_if_deps)
1074 choice.block = self._parse_block(line_feeder,
1080 choice._determine_actual_symbols()
1082 # If no type is set for the choice, its type is that of the first
1084 if choice.type == UNKNOWN:
1085 for item in choice.get_symbols():
1086 if item.type != UNKNOWN:
1087 choice.type = item.type
1090 # Each choice item of UNKNOWN type gets the type of the choice
1091 for item in choice.get_symbols():
1092 if item.type == UNKNOWN:
1093 item.type = choice.type
1095 # For named choices defined in multiple locations, only record
1096 # at the first definition
1097 if not already_defined:
1098 block.add_item(choice)
1100 elif t0 == T_COMMENT:
1102 comment.config = self
1103 comment.parent = parent
1105 comment.filename = filename
1106 comment.linenr = linenr
1108 comment.text = tokens.get_next()
1109 self._parse_properties(line_feeder, comment, deps, visible_if_deps)
1111 block.add_item(comment)
1112 self.comments.append(comment)
1114 elif t0 == T_SOURCE:
1115 kconfig_file = tokens.get_next()
1116 exp_kconfig_file = self._expand_sym_refs(kconfig_file)
1117 f = os.path.join(self.base_dir, exp_kconfig_file)
1119 if not os.path.exists(f):
1120 raise IOError, ('{0}:{1}: sourced file "{2}" (expands to\n'
1121 '"{3}") not found. Perhaps base_dir\n'
1122 '(argument to Config.__init__(), currently\n'
1123 '"{4}") is set to the wrong value.'
1130 # Add items to the same block
1131 self._parse_file(f, parent, deps, visible_if_deps, block)
1133 elif t0 == T_MAINMENU:
1134 text = tokens.get_next()
1136 if self.mainmenu_text is not None:
1137 self._warn("overriding 'mainmenu' text. "
1138 'Old value: "{0}", new value: "{1}".'
1139 .format(self.mainmenu_text, text),
1143 self.mainmenu_text = text
1146 _parse_error(line, "unrecognized construct.", filename, linenr)
1148 def _parse_properties(self, line_feeder, stmt, deps, visible_if_deps):
1149 """Parsing of properties for symbols, menus, choices, and comments."""
1151 def parse_val_and_cond(tokens, line, filename, linenr):
1152 """Parses '<expr1> if <expr2>' constructs, where the 'if' part is
1153 optional. Returns a tuple containing the parsed expressions, with
1154 None as the second element if the 'if' part is missing."""
1155 val = self._parse_expr(tokens, stmt, line, filename, linenr, False)
1157 if tokens.check(T_IF):
1158 return (val, self._parse_expr(tokens, stmt, line, filename, linenr))
1162 # In case the symbol is defined in multiple locations, we need to
1163 # remember what prompts, defaults, and selects are new for this
1164 # definition, as "depends on" should only apply to the local
1170 # Dependencies from 'depends on' statements
1171 depends_on_expr = None
1174 line = line_feeder.get_next()
1178 filename = line_feeder.get_filename()
1179 linenr = line_feeder.get_linenr()
1181 tokens = self._tokenize(line, False, filename, linenr)
1183 if tokens.is_empty():
1186 t0 = tokens.get_next()
1189 # Find first non-empty line and get its indentation
1191 line_feeder.remove_while(str.isspace)
1192 line = line_feeder.get_next()
1198 indent = _indentation(line)
1200 # If the first non-empty lines has zero indent, there is no
1204 line_feeder.go_back()
1207 help_lines = [_deindent(line, indent)]
1209 # The help text goes on till the first non-empty line with less
1212 line = line_feeder.get_next()
1213 if (line is None) or \
1214 (not line.isspace() and _indentation(line) < indent):
1215 stmt.help = "".join(help_lines)
1218 help_lines.append(_deindent(line, indent))
1223 line_feeder.go_back()
1225 elif t0 == T_PROMPT:
1226 # 'prompt' properties override each other within a single
1227 # definition of a symbol, but additional prompts can be added
1228 # by defining the symbol multiple times; hence 'new_prompt'
1229 # instead of 'prompt'.
1230 new_prompt = parse_val_and_cond(tokens, line, filename, linenr)
1232 elif t0 == T_DEFAULT:
1233 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1235 elif t0 == T_DEPENDS:
1236 if not tokens.check(T_ON):
1237 _parse_error(line, 'expected "on" after "depends".', filename, linenr)
1239 parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)
1241 if isinstance(stmt, (Menu, Comment)):
1242 stmt.dep_expr = _make_and(stmt.dep_expr, parsed_deps)
1244 depends_on_expr = _make_and(depends_on_expr, parsed_deps)
1246 elif t0 == T_VISIBLE:
1247 if not tokens.check(T_IF):
1248 _parse_error(line, 'expected "if" after "visible".', filename, linenr)
1249 if not isinstance(stmt, Menu):
1251 "'visible if' is only valid for menus.",
1255 parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)
1256 stmt.visible_if_expr = _make_and(stmt.visible_if_expr, parsed_deps)
1258 elif t0 == T_SELECT:
1259 target = tokens.get_next()
1261 stmt.referenced_syms.add(target)
1262 stmt.selected_syms.add(target)
1264 if tokens.check(T_IF):
1265 new_selects.append((target,
1266 self._parse_expr(tokens, stmt, line, filename, linenr)))
1268 new_selects.append((target, None))
1270 elif t0 in (T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING):
1271 stmt.type = token_to_type[t0]
1274 new_prompt = parse_val_and_cond(tokens, line, filename, linenr)
1277 lower = tokens.get_next()
1278 upper = tokens.get_next()
1279 stmt.referenced_syms.add(lower)
1280 stmt.referenced_syms.add(upper)
1282 if tokens.check(T_IF):
1283 stmt.ranges.append((lower, upper,
1284 self._parse_expr(tokens, stmt, line, filename, linenr)))
1286 stmt.ranges.append((lower, upper, None))
1288 elif t0 == T_DEF_BOOL:
1292 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1294 elif t0 == T_DEF_TRISTATE:
1295 stmt.type = TRISTATE
1298 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1300 elif t0 == T_OPTIONAL:
1301 if not isinstance(stmt, Choice):
1303 '"optional" is only valid for choices.',
1306 stmt.optional = True
1308 elif t0 == T_OPTION:
1309 if tokens.check(T_ENV) and tokens.check(T_EQUAL):
1310 env_var = tokens.get_next()
1312 stmt.is_special_ = True
1313 stmt.is_from_env = True
1315 if env_var not in os.environ:
1317 The symbol {0} references the non-existent environment variable {1} and will
1318 get the empty string as its value.
1320 If you're using kconfiglib via 'make (i)scriptconfig' it should have set up the
1321 environment correctly for you. If you still got this message, that might be an
1322 error, and you should e-mail kconfiglib@gmail.com.
1323 .""" .format(stmt.name, env_var),
1327 stmt.cached_value = ""
1329 stmt.cached_value = os.environ[env_var]
1331 elif tokens.check(T_DEFCONFIG_LIST):
1332 self.defconfig_sym = stmt
1334 elif tokens.check(T_MODULES):
1335 self._warn("the 'modules' option is not supported. "
1336 "Let me know if this is a problem for you; "
1337 "it shouldn't be that hard to implement. "
1338 "(Note that modules are still supported -- "
1339 "Kconfiglib just assumes the symbol name "
1344 elif tokens.check(T_ALLNOCONFIG_Y):
1345 if not isinstance(stmt, Symbol):
1347 "the 'allnoconfig_y' option is only valid for symbols.",
1350 stmt.allnoconfig_y = True
1353 _parse_error(line, "unrecognized option.", filename, linenr)
1356 # See comment in Config.__init__()
1357 self.end_line = line
1358 self.end_line_tokens = tokens
1361 # Propagate dependencies from enclosing menus and if's.
1363 # For menus and comments..
1364 if isinstance(stmt, (Menu, Comment)):
1365 stmt.orig_deps = stmt.dep_expr
1366 stmt.deps_from_containing = deps
1367 stmt.dep_expr = _make_and(stmt.dep_expr, deps)
1369 stmt.all_referenced_syms = \
1370 stmt.referenced_syms | _get_expr_syms(deps)
1372 # For symbols and choices..
1375 # See comment for 'menu_dep'
1376 stmt.menu_dep = depends_on_expr
1378 # Propagate dependencies specified with 'depends on' to any new
1379 # default expressions, prompts, and selections. ("New" since a
1380 # symbol might be defined in multiple places and the dependencies
1381 # should only apply to the local definition.)
1383 new_def_exprs = [(val_expr, _make_and(cond_expr, depends_on_expr))
1384 for (val_expr, cond_expr) in new_def_exprs]
1386 new_selects = [(target, _make_and(cond_expr, depends_on_expr))
1387 for (target, cond_expr) in new_selects]
1389 if new_prompt is not None:
1390 prompt, cond_expr = new_prompt
1392 # 'visible if' dependencies from enclosing menus get propagated
1394 if visible_if_deps is not None:
1395 cond_expr = _make_and(cond_expr, visible_if_deps)
1397 new_prompt = (prompt, _make_and(cond_expr, depends_on_expr))
1399 # We save the original expressions -- before any menu and if
1400 # conditions have been propagated -- so these can be retrieved
1403 stmt.orig_def_exprs.extend(new_def_exprs)
1404 if new_prompt is not None:
1405 stmt.orig_prompts.append(new_prompt)
1407 # Only symbols can select
1408 if isinstance(stmt, Symbol):
1409 stmt.orig_selects.extend(new_selects)
1411 # Save dependencies from enclosing menus and if's
1412 stmt.deps_from_containing = deps
1414 # The set of symbols referenced directly by the symbol/choice plus
1415 # all symbols referenced by enclosing menus and if's.
1416 stmt.all_referenced_syms = \
1417 stmt.referenced_syms | _get_expr_syms(deps)
1419 # Propagate dependencies from enclosing menus and if's
1421 stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
1422 for (val_expr, cond_expr) in new_def_exprs])
1424 for (target, cond) in new_selects:
1425 target.rev_dep = _make_or(target.rev_dep,
1427 _make_and(cond, deps)))
1429 if new_prompt is not None:
1430 prompt, cond_expr = new_prompt
1431 stmt.prompts.append((prompt, _make_and(cond_expr, deps)))
1434 # Symbol table manipulation
1437 def _sym_lookup(self, name, add_sym_if_not_exists = True):
1438 """Fetches the symbol 'name' from the symbol table, optionally adding
1439 it if it does not exist (this is usually what we want)."""
1440 if name in self.syms:
1441 return self.syms[name]
1444 new_sym.config = self
1447 if add_sym_if_not_exists:
1448 self.syms[name] = new_sym
1450 # This warning is generated while evaluating an expression
1451 # containing undefined symbols using Config.eval()
1452 self._warn("no symbol {0} in configuration".format(name))
1457 # Evaluation of symbols and expressions
1460 def _eval_expr(self, expr):
1461 """Evaluates an expression and returns one of the tristate values "n",
1463 res = self._eval_expr_2(expr)
1465 # Promote "m" to "y" if we're running without modules. Internally, "m"
1466 # is often rewritten to "m" && MODULES by both the C implementation and
1467 # kconfiglib, which takes care of cases where "m" should be false if
1468 # we're running without modules.
1469 if res == "m" and not self._has_modules():
1474 def _eval_expr_2(self, expr):
1478 if isinstance(expr, Symbol):
1479 # Non-bool/tristate symbols are always "n" in a tristate sense,
1480 # regardless of their value
1481 if expr.type != BOOL and expr.type != TRISTATE:
1483 return expr.get_value()
1485 if isinstance(expr, str):
1486 return expr if (expr == "y" or expr == "m") else "n"
1488 first_expr = expr[0]
1490 if first_expr == OR:
1493 for subexpr in expr[1]:
1494 ev = self._eval_expr_2(subexpr)
1496 # Return immediately upon discovering a "y" term
1503 # 'res' is either "n" or "m" here; we already handled the
1504 # short-circuiting "y" case in the loop.
1507 if first_expr == AND:
1510 for subexpr in expr[1]:
1511 ev = self._eval_expr_2(subexpr)
1513 # Return immediately upon discovering an "n" term
1520 # 'res' is either "m" or "y" here; we already handled the
1521 # short-circuiting "n" case in the loop.
1524 if first_expr == NOT:
1525 ev = self._eval_expr_2(expr[1])
1530 return "y" if (ev == "n") else "m"
1532 if first_expr == EQUAL:
1533 return "y" if (self._get_str_value(expr[1]) ==
1534 self._get_str_value(expr[2])) else "n"
1536 if first_expr == UNEQUAL:
1537 return "y" if (self._get_str_value(expr[1]) !=
1538 self._get_str_value(expr[2])) else "n"
1540 _internal_error("Internal error while evaluating expression: "
1541 "unknown operation {0}.".format(first_expr))
1543 def _get_str_value(self, obj):
1544 if isinstance(obj, str):
1547 return obj.get_value()
1549 def _eval_min(self, e1, e2):
1550 e1_eval = self._eval_expr(e1)
1551 e2_eval = self._eval_expr(e2)
1553 return e1_eval if tri_less(e1_eval, e2_eval) else e2_eval
1555 def _eval_max(self, e1, e2):
1556 e1_eval = self._eval_expr(e1)
1557 e2_eval = self._eval_expr(e2)
1559 return e1_eval if tri_greater(e1_eval, e2_eval) else e2_eval
1562 # Methods related to the MODULES symbol
1565 def _has_modules(self):
1566 modules_sym = self.syms.get("MODULES")
1567 return (modules_sym is not None) and (modules_sym.get_value() == "y")
1570 # Dependency tracking
1573 def _build_dep(self):
1574 """Populates the Symbol.dep sets, linking the symbol to the symbols
1575 that immediately depend on it in the sense that changing the value of
1576 the symbol might affect the values of those other symbols. This is used
1577 for caching/invalidation purposes. The calculated sets might be larger
1578 than necessary as we don't do any complicated analysis of the
1580 for sym in self.syms.itervalues():
1583 # Adds 'sym' as a directly dependent symbol to all symbols that appear
1584 # in the expression 'e'
1585 def add_expr_deps(e, sym):
1586 for s in _get_expr_syms(e):
1589 # The directly dependent symbols of a symbol are:
1590 # - Any symbols whose prompts, default values, rev_dep (select
1591 # condition), or ranges depend on the symbol
1592 # - Any symbols that belong to the same choice statement as the symbol
1593 # (these won't be included in 'dep' as that makes the dependency
1594 # graph unwieldy, but Symbol._get_dependent() will include them)
1595 # - Any symbols in a choice statement that depends on the symbol
1596 for sym in self.syms.itervalues():
1597 for (_, e) in sym.prompts:
1598 add_expr_deps(e, sym)
1600 for (v, e) in sym.def_exprs:
1601 add_expr_deps(v, sym)
1602 add_expr_deps(e, sym)
1604 add_expr_deps(sym.rev_dep, sym)
1606 for (l, u, e) in sym.ranges:
1607 add_expr_deps(l, sym)
1608 add_expr_deps(u, sym)
1609 add_expr_deps(e, sym)
1611 if sym.is_choice_symbol_:
1614 for (_, e) in choice.prompts:
1615 add_expr_deps(e, sym)
1617 for (_, e) in choice.def_exprs:
1618 add_expr_deps(e, sym)
1620 def _expr_val_str(self, expr, no_value_str = "(none)", get_val_instead_of_eval = False):
1621 # Since values are valid expressions, _expr_to_str() will get a nice
1622 # string representation for those as well.
1627 if get_val_instead_of_eval:
1628 if isinstance(expr, str):
1629 return _expr_to_str(expr)
1630 val = expr.get_value()
1632 val = self._eval_expr(expr)
1634 return "{0} (value: {1})".format(_expr_to_str(expr), _expr_to_str(val))
1636 def _expand_sym_refs(self, s):
1637 """Expands $-references to symbols in 's' to symbol values, or to the
1638 empty string for undefined symbols."""
1641 sym_ref_re_match = sym_ref_re.search(s)
1642 if sym_ref_re_match is None:
1645 sym_name = sym_ref_re_match.group(0)[1:]
1646 sym = self.syms.get(sym_name)
1647 expansion = "" if sym is None else sym.get_value()
1649 s = s[:sym_ref_re_match.start()] + \
1651 s[sym_ref_re_match.end():]
1653 def _get_sym_or_choice_str(self, sc):
1654 """Symbols and choices have many properties in common, so we factor out
1655 common __str__() stuff here. "sc" is short for "symbol or choice"."""
1657 # As we deal a lot with string representations here, use some
1658 # convenient shorthand:
1662 # Common symbol/choice properties
1665 user_value_str = "(no user value)" if sc.user_val is None else s(sc.user_val)
1667 visibility_str = s(sc.get_visibility())
1669 # Build prompts string
1670 if sc.prompts == []:
1671 prompts_str = " (no prompts)"
1673 prompts_str_rows = []
1675 for (prompt, cond_expr) in sc.orig_prompts:
1676 if cond_expr is None:
1677 prompts_str_rows.append(' "{0}"'.format(prompt))
1679 prompts_str_rows.append(' "{0}" if '.format(prompt) +
1680 self._expr_val_str(cond_expr))
1682 prompts_str = "\n".join(prompts_str_rows)
1684 # Build locations string
1685 if sc.def_locations == []:
1686 locations_str = "(no locations)"
1688 locations_str = " ".join(["{0}:{1}".format(filename, linenr) for
1689 (filename, linenr) in sc.def_locations])
1691 # Build additional-dependencies-from-menus-and-if's string
1692 additional_deps_str = " " + self._expr_val_str(sc.deps_from_containing,
1693 "(no additional dependencies)")
1696 # Symbol-specific stuff
1699 if isinstance(sc, Symbol):
1701 # Build value string
1702 value_str = s(sc.get_value())
1704 # Build ranges string
1705 if isinstance(sc, Symbol):
1707 ranges_str = " (no ranges)"
1709 ranges_str_rows = []
1711 for (l, u, cond_expr) in sc.ranges:
1712 if cond_expr is None:
1713 ranges_str_rows.append(" [{0}, {1}]".format(s(l), s(u)))
1715 ranges_str_rows.append(" [{0}, {1}] if {2}"
1716 .format(s(l), s(u), self._expr_val_str(cond_expr)))
1718 ranges_str = "\n".join(ranges_str_rows)
1720 # Build default values string
1721 if sc.def_exprs == []:
1722 defaults_str = " (no default values)"
1724 defaults_str_rows = []
1726 for (val_expr, cond_expr) in sc.orig_def_exprs:
1727 row_str = " " + self._expr_val_str(val_expr, "(none)", sc.type == STRING)
1728 defaults_str_rows.append(row_str)
1729 defaults_str_rows.append(" Condition: " + self._expr_val_str(cond_expr))
1731 defaults_str = "\n".join(defaults_str_rows)
1733 # Build selects string
1734 if sc.orig_selects == []:
1735 selects_str = " (no selects)"
1737 selects_str_rows = []
1739 for (target, cond_expr) in sc.orig_selects:
1740 if cond_expr is None:
1741 selects_str_rows.append(" {0}".format(target.name))
1743 selects_str_rows.append(" {0} if ".format(target.name) +
1744 self._expr_val_str(cond_expr))
1746 selects_str = "\n".join(selects_str_rows)
1748 # Build reverse dependencies string
1749 if sc.rev_dep == "n":
1750 rev_dep_str = " (no reverse dependencies)"
1752 rev_dep_str = " " + self._expr_val_str(sc.rev_dep)
1754 res = _sep_lines("Symbol " + (sc.name if sc.name is not None else "(no name)"),
1755 "Type : " + typename[sc.type],
1756 "Value : " + value_str,
1757 "User value : " + user_value_str,
1758 "Visibility : " + visibility_str,
1759 "Is choice item : " + bool_str[sc.is_choice_symbol_],
1760 "Is defined : " + bool_str[sc.is_defined_],
1761 "Is from env. : " + bool_str[sc.is_from_env],
1762 "Is special : " + bool_str[sc.is_special_] + "\n")
1765 res += _sep_lines("Ranges:",
1768 res += _sep_lines("Prompts:",
1774 "Reverse dependencies:",
1776 "Additional dependencies from enclosing menus and if's:",
1777 additional_deps_str,
1778 "Locations: " + locations_str)
1783 # Choice-specific stuff
1786 # Build name string (for named choices)
1788 name_str = "(no name)"
1792 # Build selected symbol string
1793 sel = sc.get_selection()
1795 sel_str = "(no selection)"
1800 mode_str = s(sc.get_mode())
1802 # Build default values string
1803 if sc.def_exprs == []:
1804 defaults_str = " (no default values)"
1806 defaults_str_rows = []
1808 for (sym, cond_expr) in sc.orig_def_exprs:
1809 if cond_expr is None:
1810 defaults_str_rows.append(" {0}".format(sym.name))
1812 defaults_str_rows.append(" {0} if ".format(sym.name) +
1813 self._expr_val_str(cond_expr))
1815 defaults_str = "\n".join(defaults_str_rows)
1817 # Build contained symbols string
1818 names = [sym.name for sym in sc.get_symbols()]
1821 syms_string = "(empty)"
1823 syms_string = " ".join(names)
1825 return _sep_lines("Choice",
1826 "Name (for named choices): " + name_str,
1827 "Type : " + typename[sc.type],
1828 "Selected symbol : " + sel_str,
1829 "User value : " + user_value_str,
1830 "Mode : " + mode_str,
1831 "Visibility : " + visibility_str,
1832 "Optional : " + bool_str[sc.optional],
1839 "Additional dependencies from enclosing menus and if's:",
1840 additional_deps_str,
1841 "Locations: " + locations_str)
1843 def _expr_depends_on(self, expr, sym):
1844 """Reimplementation of expr_depends_symbol() from mconf.c. Used to
1845 determine if a submenu should be implicitly created, which influences what
1846 items inside choice statements are considered choice items."""
1851 if isinstance(expr, str):
1854 if isinstance(expr, Symbol):
1859 if e0 == EQUAL or e0 == UNEQUAL:
1860 return self._eq_to_sym(expr) is sym
1863 for and_expr in expr[1]:
1871 def _eq_to_sym(self, eq):
1872 """_expr_depends_on() helper. For (in)equalities of the form sym = y/m
1873 or sym != n, returns sym. For other (in)equalities, returns None."""
1874 relation, left, right = eq
1876 left = self._transform_n_m_y(left)
1877 right = self._transform_n_m_y(right)
1879 # Make sure the symbol (if any) appears to the left
1880 if not isinstance(left, Symbol):
1881 left, right = right, left
1883 if not isinstance(left, Symbol):
1886 if (relation == EQUAL and (right == "m" or right == "y")) or \
1887 (relation == UNEQUAL and right == "n"):
1892 def _transform_n_m_y(self, item):
1893 """_eq_to_sym() helper. Translates the symbols n, m, and y to their
1894 string equivalents."""
1903 def _warn(self, msg, filename = None, linenr = None):
1904 """For printing warnings to stderr."""
1905 if self.print_warnings:
1906 self._warn_or_undef_assign(msg, WARNING, filename, linenr)
1908 def _undef_assign(self, msg, filename = None, linenr = None):
1909 """For printing informational messages related to assignments
1910 to undefined variables to stderr."""
1911 if self.print_undef_assign:
1912 self._warn_or_undef_assign(msg, UNDEF_ASSIGN, filename, linenr)
1914 def _warn_or_undef_assign(self, msg, msg_type, filename, linenr):
1915 if filename is not None:
1916 sys.stderr.write("{0}:".format(_clean_up_path(filename)))
1917 if linenr is not None:
1918 sys.stderr.write("{0}:".format(linenr))
1920 if msg_type == WARNING:
1921 sys.stderr.write("warning: ")
1922 elif msg_type == UNDEF_ASSIGN:
1923 sys.stderr.write("info: ")
1925 _internal_error('Internal error while printing warning: unknown warning type "{0}".'
1928 sys.stderr.write(msg + "\n")
1930 def _get_expr_syms(expr):
1931 """Returns the set() of symbols appearing in expr."""
1937 if isinstance(expr, Symbol):
1941 if isinstance(expr, str):
1946 if e0 == OR or e0 == AND:
1947 for term in expr[1]:
1953 elif e0 == EQUAL or e0 == UNEQUAL:
1956 if isinstance(v1, Symbol):
1959 if isinstance(v2, Symbol):
1963 _internal_error("Internal error while fetching symbols from an "
1964 "expression with token stream {0}.".format(expr))
1971 # Construction of expressions
1974 # These functions as well as the _eval_min/max() functions above equate
1975 # None with "y", which is usually what we want, but needs to be kept in
1978 def _make_or(e1, e2):
1979 # Perform trivial simplification and avoid None's (which
1980 # correspond to y's)
1981 if e1 is None or e2 is None or \
1982 e1 == "y" or e2 == "y":
1991 # Prefer to merge/update argument list if possible instead of creating
1994 if isinstance(e1, tuple) and e1[0] == OR:
1995 if isinstance(e2, tuple) and e2[0] == OR:
1996 return (OR, e1[1] + e2[1])
1997 return (OR, e1[1] + [e2])
1999 if isinstance(e2, tuple) and e2[0] == OR:
2000 return (OR, e2[1] + [e1])
2002 return (OR, [e1, e2])
2004 # Note: returns None if e1 == e2 == None
2006 def _make_and(e1, e2):
2007 if e1 == "n" or e2 == "n":
2010 if e1 is None or e1 == "y":
2013 if e2 is None or e2 == "y":
2016 # Prefer to merge/update argument list if possible instead of creating
2019 if isinstance(e1, tuple) and e1[0] == AND:
2020 if isinstance(e2, tuple) and e2[0] == AND:
2021 return (AND, e1[1] + e2[1])
2022 return (AND, e1[1] + [e2])
2024 if isinstance(e2, tuple) and e2[0] == AND:
2025 return (AND, e2[1] + [e1])
2027 return (AND, [e1, e2])
2030 # Constants and functions related to types, parsing, evaluation and printing,
2031 # put globally to unclutter the Config class a bit.
2035 (T_OR, T_AND, T_NOT,
2036 T_OPEN_PAREN, T_CLOSE_PAREN,
2038 T_MAINMENU, T_MENU, T_ENDMENU,
2039 T_SOURCE, T_CHOICE, T_ENDCHOICE,
2040 T_COMMENT, T_CONFIG, T_MENUCONFIG,
2041 T_HELP, T_IF, T_ENDIF, T_DEPENDS, T_ON,
2042 T_OPTIONAL, T_PROMPT, T_DEFAULT,
2043 T_BOOL, T_TRISTATE, T_HEX, T_INT, T_STRING,
2044 T_DEF_BOOL, T_DEF_TRISTATE,
2045 T_SELECT, T_RANGE, T_OPTION, T_ALLNOCONFIG_Y, T_ENV,
2046 T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(0, 39)
2048 # Keyword to token map
2050 "mainmenu" : T_MAINMENU,
2052 "endmenu" : T_ENDMENU,
2054 "endchoice" : T_ENDCHOICE,
2055 "source" : T_SOURCE,
2056 "choice" : T_CHOICE,
2057 "config" : T_CONFIG,
2058 "comment" : T_COMMENT,
2059 "menuconfig" : T_MENUCONFIG,
2062 "depends" : T_DEPENDS,
2064 "optional" : T_OPTIONAL,
2065 "prompt" : T_PROMPT,
2066 "default" : T_DEFAULT,
2069 "tristate" : T_TRISTATE,
2072 "def_bool" : T_DEF_BOOL,
2073 "def_tristate" : T_DEF_TRISTATE,
2074 "string" : T_STRING,
2075 "select" : T_SELECT,
2077 "option" : T_OPTION,
2078 "allnoconfig_y" : T_ALLNOCONFIG_Y,
2080 "defconfig_list" : T_DEFCONFIG_LIST,
2081 "modules" : T_MODULES,
2082 "visible" : T_VISIBLE }
2084 # Strings to use for True and False
2085 bool_str = { False : "false", True : "true" }
2087 # Tokens after which identifier-like lexemes are treated as strings. T_CHOICE
2088 # is included to avoid symbols being registered for named choices.
2089 string_lex = frozenset((T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING, T_CHOICE,
2090 T_PROMPT, T_MENU, T_COMMENT, T_SOURCE, T_MAINMENU))
2092 # Matches the initial token on a line; see _tokenize().
2093 initial_token_re = re.compile(r"[^\w]*(\w+)")
2095 # Matches an identifier/keyword optionally preceded by whitespace
2096 id_keyword_re = re.compile(r"\s*([\w./-]+)")
2098 # Regular expressions for parsing .config files
2099 set_re = re.compile(r"CONFIG_(\w+)=(.*)")
2100 unset_re = re.compile(r"# CONFIG_(\w+) is not set")
2102 # Regular expression for finding $-references to symbols in strings
2103 sym_ref_re = re.compile(r"\$[A-Za-z0-9_]+")
2105 # Integers representing symbol types
2106 UNKNOWN, BOOL, TRISTATE, STRING, HEX, INT = range(0, 6)
2108 # Strings to use for types
2110 UNKNOWN : "unknown",
2112 TRISTATE : "tristate",
2117 # Token to type mapping
2118 token_to_type = { T_BOOL : BOOL,
2119 T_TRISTATE : TRISTATE,
2124 # Default values for symbols of different types (the value the symbol gets if
2125 # it is not assigned a user value and none of its 'default' clauses kick in)
2126 default_value = { BOOL : "n",
2132 # Indicates that no item is selected in a choice statement
2135 # Integers representing expression types
2136 OR, AND, NOT, EQUAL, UNEQUAL = range(0, 5)
2138 # Map from tristate values to integers
2139 tri_to_int = { "n" : 0, "m" : 1, "y" : 2 }
2141 # Printing-related stuff
2143 op_to_str = { AND : " && ",
2148 precedence = { OR : 0, AND : 1, NOT : 2 }
2150 # Types of informational messages
2154 def _intersperse(lst, op):
2155 """_expr_to_str() helper. Gets the string representation of each expression in lst
2156 and produces a list where op has been inserted between the elements."""
2162 def handle_sub_expr(expr):
2163 no_parens = isinstance(expr, (str, Symbol)) or \
2164 expr[0] in (EQUAL, UNEQUAL) or \
2165 precedence[op] <= precedence[expr[0]]
2168 res.extend(_expr_to_str_rec(expr))
2172 op_str = op_to_str[op]
2174 handle_sub_expr(lst[0])
2175 for expr in lst[1:]:
2177 handle_sub_expr(expr)
2181 def _expr_to_str(expr):
2182 s = "".join(_expr_to_str_rec(expr))
2185 def _sym_str_string(sym_or_str):
2186 if isinstance(sym_or_str, str):
2187 return '"{0}"'.format(sym_or_str)
2188 return sym_or_str.name
2190 def _expr_to_str_rec(expr):
2194 if isinstance(expr, (Symbol, str)):
2195 return [_sym_str_string(expr)]
2199 if e0 == OR or e0 == AND:
2200 return _intersperse(expr[1], expr[0])
2203 need_parens = not isinstance(expr[1], (str, Symbol))
2208 res.extend(_expr_to_str_rec(expr[1]))
2213 if e0 == EQUAL or e0 == UNEQUAL:
2214 return [_sym_str_string(expr[1]),
2216 _sym_str_string(expr[2])]
2220 """Represents a list of items (symbols, menus, choice statements and
2221 comments) appearing at the top-level of a file or witin a menu, choice or
2227 def get_items(self):
2230 def add_item(self, item):
2231 self.items.append(item)
2233 def _make_conf(self):
2234 # Collect the substrings in a list and later use join() instead of +=
2235 # to build the final .config contents. With older Python versions, this
2236 # yields linear instead of quadratic complexity.
2238 for item in self.items:
2239 strings.extend(item._make_conf())
2243 def add_depend_expr(self, expr):
2244 for item in self.items:
2245 item.add_depend_expr(expr)
2249 """Base class for symbols and other Kconfig constructs. Subclasses are
2250 Symbol, Choice, Menu, and Comment."""
2252 def is_symbol(self):
2253 """Returns True if the item is a symbol, otherwise False. Short for
2254 isinstance(item, kconfiglib.Symbol)."""
2255 return isinstance(self, Symbol)
2257 def is_choice(self):
2258 """Returns True if the item is a choice, otherwise False. Short for
2259 isinstance(item, kconfiglib.Choice)."""
2260 return isinstance(self, Choice)
2263 """Returns True if the item is a menu, otherwise False. Short for
2264 isinstance(item, kconfiglib.Menu)."""
2265 return isinstance(self, Menu)
2267 def is_comment(self):
2268 """Returns True if the item is a comment, otherwise False. Short for
2269 isinstance(item, kconfiglib.Comment)."""
2270 return isinstance(self, Comment)
2272 class _HasVisibility():
2274 """Base class for elements that have a "visibility" that acts as an upper
2275 limit on the values a user can set for them. Subclasses are Symbol and
2276 Choice (which supply some of the attributes)."""
2279 self.cached_visibility = None
2282 def _invalidate(self):
2283 self.cached_visibility = None
2285 def _get_visibility(self):
2286 if self.cached_visibility is None:
2288 for (prompt, cond_expr) in self.prompts:
2289 vis = self.config._eval_max(vis, cond_expr)
2291 if isinstance(self, Symbol) and self.is_choice_symbol_:
2292 vis = self.config._eval_min(vis, self.parent._get_visibility())
2294 # Promote "m" to "y" if we're dealing with a non-tristate
2295 if vis == "m" and self.type != TRISTATE:
2298 self.cached_visibility = vis
2300 return self.cached_visibility
2302 class Symbol(Item, _HasVisibility):
2304 """Represents a configuration symbol - e.g. FOO for
2313 def get_value(self):
2314 """Calculate and return the value of the symbol. See also
2315 Symbol.set_user_value()."""
2317 if self.cached_value is not None:
2318 return self.cached_value
2320 self.write_to_conf = False
2322 # As a quirk of Kconfig, undefined symbols get their name as their
2323 # value. This is why things like "FOO = bar" work for seeing if FOO has
2325 if self.type == UNKNOWN:
2326 self.cached_value = self.name
2329 new_val = default_value[self.type]
2331 vis = self._get_visibility()
2333 if self.type == BOOL or self.type == TRISTATE:
2334 # The visibility and mode (modules-only or single-selection) of
2335 # choice items will be taken into account in self._get_visibility()
2337 if self.is_choice_symbol_:
2339 choice = self.parent
2340 mode = choice.get_mode()
2342 self.write_to_conf = (mode != "n")
2345 new_val = "y" if (choice.get_selection() is self) else "n"
2347 if self.user_val == "m" or self.user_val == "y":
2354 # If the symbol is visible and has a user value, use that.
2355 # Otherwise, look at defaults.
2356 self.write_to_conf = True
2358 if self.user_val is not None:
2359 new_val = self.config._eval_min(self.user_val, vis)
2360 use_defaults = False
2363 for (val_expr, cond_expr) in self.def_exprs:
2364 cond_eval = self.config._eval_expr(cond_expr)
2366 if cond_eval != "n":
2367 self.write_to_conf = True
2368 new_val = self.config._eval_min(val_expr, cond_eval)
2371 # Reverse dependencies take precedence
2372 rev_dep_val = self.config._eval_expr(self.rev_dep)
2374 if rev_dep_val != "n":
2375 self.write_to_conf = True
2376 new_val = self.config._eval_max(new_val, rev_dep_val)
2378 # Promote "m" to "y" for booleans
2379 if new_val == "m" and self.type == BOOL:
2382 elif self.type == STRING:
2386 self.write_to_conf = True
2387 if self.user_val is not None:
2388 new_val = self.user_val
2389 use_defaults = False
2392 for (val_expr, cond_expr) in self.def_exprs:
2393 if self.config._eval_expr(cond_expr) != "n":
2394 self.write_to_conf = True
2395 new_val = self.config._get_str_value(val_expr)
2398 elif self.type == HEX or self.type == INT:
2399 has_active_range = False
2404 base = 16 if self.type == HEX else 10
2406 for(l, h, cond_expr) in self.ranges:
2407 if self.config._eval_expr(cond_expr) != "n":
2408 has_active_range = True
2410 low_str = self.config._get_str_value(l)
2411 high_str = self.config._get_str_value(h)
2413 low = int(low_str, base) if \
2414 _is_base_n(low_str, base) else 0
2415 high = int(high_str, base) if \
2416 _is_base_n(high_str, base) else 0
2421 self.write_to_conf = True
2423 if self.user_val is not None and \
2424 _is_base_n(self.user_val, base) and \
2425 (not has_active_range or
2426 low <= int(self.user_val, base) <= high):
2428 # If the user value is OK, it is stored in exactly the same
2429 # form as specified in the assignment (with or without
2432 use_defaults = False
2433 new_val = self.user_val
2436 for (val_expr, cond_expr) in self.def_exprs:
2437 if self.config._eval_expr(cond_expr) != "n":
2438 self.write_to_conf = True
2440 # If the default value is OK, it is stored in exactly
2441 # the same form as specified. Otherwise, it is clamped
2442 # to the range, and the output has "0x" as appropriate
2445 new_val = self.config._get_str_value(val_expr)
2447 if _is_base_n(new_val, base):
2448 new_val_num = int(new_val, base)
2449 if has_active_range:
2452 if new_val_num < low:
2454 elif new_val_num > high:
2457 if clamped_val is not None:
2458 new_val = (hex(clamped_val) if \
2459 self.type == HEX else str(clamped_val))
2462 else: # For the for loop
2463 # If no user value or default kicks in but the hex/int has
2464 # an active range, then the low end of the range is used,
2465 # provided it's > 0, with "0x" prepended as appropriate.
2467 if has_active_range and low > 0:
2468 new_val = (hex(low) if self.type == HEX else str(low))
2470 self.cached_value = new_val
2473 def set_user_value(self, v):
2474 """Sets the user value of the symbol.
2476 Equal in effect to assigning the value to the symbol within a .config
2477 file. Use get_lower/upper_bound() or get_assignable_values() to find
2478 the range of currently assignable values for bool and tristate symbols;
2479 setting values outside this range will cause the user value to differ
2480 from the result of Symbol.get_value() (be truncated). Values that are
2481 invalid for the type (such as a_bool.set_user_value("foo")) are
2482 ignored, and a warning is emitted if an attempt is made to assign such
2485 For any type of symbol, is_modifiable() can be used to check if a user
2486 value will currently have any effect on the symbol, as determined by
2487 its visibility and range of assignable values. Any value that is valid
2488 for the type (bool, tristate, etc.) will end up being reflected in
2489 get_user_value() though, and might have an effect later if conditions
2490 change. To get rid of the user value, use unset_user_value().
2492 Any symbols dependent on the symbol are (recursively) invalidated, so
2493 things will just work with regards to dependencies.
2495 v -- The user value to give to the symbol."""
2496 self._set_user_value_no_invalidate(v, False)
2498 # There might be something more efficient you could do here, but play
2500 if self.name == "MODULES":
2501 self.config._invalidate_all()
2505 self._invalidate_dependent()
2507 def unset_user_value(self):
2508 """Resets the user value of the symbol, as if the symbol had never
2509 gotten a user value via Config.load_config() or
2510 Symbol.set_user_value()."""
2511 self._unset_user_value_no_recursive_invalidate()
2512 self._invalidate_dependent()
2514 def get_user_value(self):
2515 """Returns the value assigned to the symbol in a .config or via
2516 Symbol.set_user_value() (provided the value was valid for the type of the
2517 symbol). Returns None in case of no user value."""
2518 return self.user_val
2521 """Returns the name of the symbol."""
2524 def get_prompts(self):
2525 """Returns a list of prompts defined for the symbol, in the order they
2526 appear in the configuration files. Returns the empty list for symbols
2529 This list will have a single entry for the vast majority of symbols
2530 having prompts, but having multiple prompts for a single symbol is
2531 possible through having multiple 'config' entries for it."""
2532 return [prompt for prompt, _ in self.orig_prompts]
2534 def get_upper_bound(self):
2535 """For string/hex/int symbols and for bool and tristate symbols that
2536 cannot be modified (see is_modifiable()), returns None.
2538 Otherwise, returns the highest value the symbol can be set to with
2539 Symbol.set_user_value() (that will not be truncated): one of "m" or "y",
2540 arranged from lowest to highest. This corresponds to the highest value
2541 the symbol could be given in e.g. the 'make menuconfig' interface.
2543 See also the tri_less*() and tri_greater*() functions, which could come
2545 if self.type != BOOL and self.type != TRISTATE:
2547 rev_dep = self.config._eval_expr(self.rev_dep)
2548 # A bool selected to "m" gets promoted to "y"
2549 if self.type == BOOL and rev_dep == "m":
2551 vis = self._get_visibility()
2552 if (tri_to_int[vis] - tri_to_int[rev_dep]) > 0:
2556 def get_lower_bound(self):
2557 """For string/hex/int symbols and for bool and tristate symbols that
2558 cannot be modified (see is_modifiable()), returns None.
2560 Otherwise, returns the lowest value the symbol can be set to with
2561 Symbol.set_user_value() (that will not be truncated): one of "n" or "m",
2562 arranged from lowest to highest. This corresponds to the lowest value
2563 the symbol could be given in e.g. the 'make menuconfig' interface.
2565 See also the tri_less*() and tri_greater*() functions, which could come
2567 if self.type != BOOL and self.type != TRISTATE:
2569 rev_dep = self.config._eval_expr(self.rev_dep)
2570 # A bool selected to "m" gets promoted to "y"
2571 if self.type == BOOL and rev_dep == "m":
2573 if (tri_to_int[self._get_visibility()] - tri_to_int[rev_dep]) > 0:
2577 def get_assignable_values(self):
2578 """For string/hex/int symbols and for bool and tristate symbols that
2579 cannot be modified (see is_modifiable()), returns the empty list.
2581 Otherwise, returns a list containing the user values that can be
2582 assigned to the symbol (that won't be truncated). Usage example:
2584 if "m" in sym.get_assignable_values():
2585 sym.set_user_value("m")
2587 This is basically a more convenient interface to
2588 get_lower/upper_bound() when wanting to test if a particular tristate
2589 value can be assigned."""
2590 if self.type != BOOL and self.type != TRISTATE:
2592 rev_dep = self.config._eval_expr(self.rev_dep)
2593 # A bool selected to "m" gets promoted to "y"
2594 if self.type == BOOL and rev_dep == "m":
2596 res = ["n", "m", "y"][tri_to_int[rev_dep] :
2597 tri_to_int[self._get_visibility()] + 1]
2598 return res if len(res) > 1 else []
2601 """Returns the type of the symbol: one of UNKNOWN, BOOL, TRISTATE,
2602 STRING, HEX, or INT. These are defined at the top level of the module,
2603 so you'd do something like
2605 if sym.get_type() == kconfiglib.STRING:
2609 def get_visibility(self):
2610 """Returns the visibility of the symbol: one of "n", "m" or "y". For
2611 bool and tristate symbols, this is an upper bound on the value users
2612 can set for the symbol. For other types of symbols, a visibility of "n"
2613 means the user value will be ignored. A visibility of "n" corresponds
2614 to not being visible in the 'make *config' interfaces.
2616 Example (assuming we're running with modules enabled -- i.e., MODULES
2619 # Assume this has been assigned 'n'
2623 # Assume this has been assigned 'm'
2627 # Has visibility 'n'
2632 # Has visibility 'm'
2637 # Has visibility 'y'
2641 # Has no prompt, and hence visibility 'n'
2645 Having visibility be tri-valued ensures that e.g. a symbol cannot be
2646 set to "y" by the user if it depends on a symbol with value "m", which
2649 You should probably look at get_lower/upper_bound(),
2650 get_assignable_values() and is_modifiable() before using this."""
2651 return self._get_visibility()
2653 def get_parent(self):
2654 """Returns the menu or choice statement that contains the symbol, or
2655 None if the symbol is at the top level. Note that if statements are
2656 treated as syntactic and do not have an explicit class
2660 def get_referenced_symbols(self, refs_from_enclosing = False):
2661 """Returns the set() of all symbols referenced by this symbol. For
2662 example, the symbol defined by
2666 prompt "foo" if A && B
2671 references the symbols A through G.
2673 refs_from_enclosing (default: False) -- If True, the symbols
2674 referenced by enclosing menus and if's will be
2675 included in the result."""
2676 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
2678 def get_selected_symbols(self):
2679 """Returns the set() of all symbols X for which this symbol has a
2680 'select X' or 'select X if Y' (regardless of whether Y is satisfied or
2681 not). This is a subset of the symbols returned by
2682 get_referenced_symbols()."""
2683 return self.selected_syms
2686 """Returns the help text of the symbol, or None if the symbol has no
2690 def get_config(self):
2691 """Returns the Config instance this symbol is from."""
2694 def get_def_locations(self):
2695 """Returns a list of (filename, linenr) tuples, where filename (string)
2696 and linenr (int) represent a location where the symbol is defined. For
2697 the vast majority of symbols this list will only contain one element.
2698 For the following Kconfig, FOO would get two entries: the lines marked
2707 return self.def_locations
2709 def get_ref_locations(self):
2710 """Returns a list of (filename, linenr) tuples, where filename (string)
2711 and linenr (int) represent a location where the symbol is referenced in
2712 the configuration. For example, the lines marked by * would be included
2717 default BAR || FOO *
2729 config FOO (definition not included)
2732 return self.ref_locations
2734 def is_modifiable(self):
2735 """Returns True if the value of the symbol could be modified by calling
2736 Symbol.set_user_value() and False otherwise.
2738 For bools and tristates, this corresponds to the symbol being visible
2739 in the 'make menuconfig' interface and not already being pinned to a
2740 specific value (e.g. because it is selected by another symbol).
2742 For strings and numbers, this corresponds to just being visible. (See
2743 Symbol.get_visibility().)"""
2744 if self.is_special_:
2746 if self.type == BOOL or self.type == TRISTATE:
2747 rev_dep = self.config._eval_expr(self.rev_dep)
2748 # A bool selected to "m" gets promoted to "y"
2749 if self.type == BOOL and rev_dep == "m":
2751 return (tri_to_int[self._get_visibility()] -
2752 tri_to_int[rev_dep]) > 0
2753 return self._get_visibility() != "n"
2755 def is_defined(self):
2756 """Returns False if the symbol is referred to in the Kconfig but never
2757 actually defined, otherwise True."""
2758 return self.is_defined_
2760 def is_special(self):
2761 """Returns True if the symbol is one of the special symbols n, m, y, or
2762 UNAME_RELEASE, or gets its value from the environment. Otherwise,
2764 return self.is_special_
2766 def is_from_environment(self):
2767 """Returns True if the symbol gets its value from the environment.
2768 Otherwise, returns False."""
2769 return self.is_from_env
2771 def has_ranges(self):
2772 """Returns True if the symbol is of type INT or HEX and has ranges that
2773 limits what values it can take on, otherwise False."""
2774 return self.ranges != []
2776 def is_choice_symbol(self):
2777 """Returns True if the symbol is in a choice statement and is an actual
2778 choice symbol (see Choice.get_symbols()); otherwise, returns
2780 return self.is_choice_symbol_
2782 def is_choice_selection(self):
2783 """Returns True if the symbol is contained in a choice statement and is
2784 the selected item, otherwise False. Equivalent to 'sym.is_choice_symbol()
2785 and sym.get_parent().get_selection() is sym'."""
2786 return self.is_choice_symbol_ and self.parent.get_selection() is self
2788 def is_allnoconfig_y(self):
2789 """Returns True if the symbol has the 'allnoconfig_y' option set;
2790 otherwise, returns False."""
2791 return self.allnoconfig_y
2794 """Returns a string containing various information about the symbol."""
2795 return self.config._get_sym_or_choice_str(self)
2802 """Symbol constructor -- not intended to be called directly by
2803 kconfiglib clients."""
2805 # Set default values
2806 _HasVisibility.__init__(self)
2818 # The prompt, default value and select conditions without any
2819 # dependencies from menus or if's propagated to them
2821 self.orig_prompts = []
2822 self.orig_def_exprs = []
2823 self.orig_selects = []
2825 # Dependencies inherited from containing menus and if's
2826 self.deps_from_containing = None
2830 # The set of symbols referenced by this symbol (see
2831 # get_referenced_symbols())
2832 self.referenced_syms = set()
2834 # The set of symbols selected by this symbol (see
2835 # get_selected_symbols())
2836 self.selected_syms = set()
2838 # Like 'referenced_syms', but includes symbols from
2839 # dependencies inherited from enclosing menus and if's
2840 self.all_referenced_syms = set()
2842 # This is set to True for "actual" choice symbols. See
2843 # Choice._determine_actual_symbols(). The trailing underscore avoids a
2844 # collision with is_choice_symbol().
2845 self.is_choice_symbol_ = False
2847 # This records only dependencies specified with 'depends on'. Needed
2848 # when determining actual choice items (hrrrr...). See also
2849 # Choice._determine_actual_symbols().
2850 self.menu_dep = None
2852 # See Symbol.get_ref/def_locations().
2853 self.def_locations = []
2854 self.ref_locations = []
2856 self.user_val = None
2860 # Should the symbol get an entry in .config?
2861 self.write_to_conf = False
2863 # Caches the calculated value
2864 self.cached_value = None
2866 # Note: An instance variable 'self.dep' gets set on the Symbol in
2867 # Config._build_dep(), linking the symbol to the symbols that
2868 # immediately depend on it (in a caching/invalidation sense). The total
2869 # set of dependent symbols for the symbol (the transitive closure) is
2870 # calculated on an as-needed basis in _get_dependent().
2872 # Caches the total list of dependent symbols. Calculated in
2874 self.cached_deps = None
2876 # Does the symbol have an entry in the Kconfig file? The trailing
2877 # underscore avoids a collision with is_defined().
2878 self.is_defined_ = False
2880 # Does the symbol get its value in some special way, e.g. from the
2881 # environment or by being one of the special symbols n, m, and y? If
2882 # so, the value is stored in self.cached_value, which is never
2883 # invalidated. The trailing underscore avoids a collision with
2885 self.is_special_ = False
2887 # Does the symbol get its value from the environment?
2888 self.is_from_env = False
2890 # Does the symbol have the 'allnoconfig_y' option set?
2891 self.allnoconfig_y = False
2893 def _invalidate(self):
2894 if self.is_special_:
2897 if self.is_choice_symbol_:
2898 self.parent._invalidate()
2900 _HasVisibility._invalidate(self)
2902 self.write_to_conf = False
2903 self.cached_value = None
2905 def _invalidate_dependent(self):
2906 for sym in self._get_dependent():
2909 def _set_user_value_no_invalidate(self, v, suppress_load_warnings):
2910 """Like set_user_value(), but does not invalidate any symbols.
2912 suppress_load_warnings --
2913 some warnings are annoying when loading a .config that can be helpful
2914 when manually invoking set_user_value(). This flag is set to True to
2915 suppress such warnings.
2917 Perhaps this could be made optional for load_config() instead."""
2919 if self.is_special_:
2920 if self.is_from_env:
2921 self.config._warn('attempt to assign the value "{0}" to the '
2922 'symbol {1}, which gets its value from the '
2923 'environment. Assignment ignored.'
2924 .format(v, self.name))
2926 self.config._warn('attempt to assign the value "{0}" to the '
2927 'special symbol {1}. Assignment ignored.'
2928 .format(v, self.name))
2933 if not self.is_defined_:
2934 filename, linenr = self.ref_locations[0]
2936 self.config._undef_assign('attempt to assign the value "{0}" to {1}, '
2937 "which is referenced at {2}:{3} but never "
2938 "defined. Assignment ignored."
2939 .format(v, self.name, filename, linenr))
2942 # Check if the value is valid for our type
2944 if not (( self.type == BOOL and (v == "n" or v == "y") ) or
2945 ( self.type == TRISTATE and (v == "n" or v == "m" or
2947 ( self.type == STRING ) or
2948 ( self.type == INT and _is_base_n(v, 10) ) or
2949 ( self.type == HEX and _is_base_n(v, 16) )):
2951 self.config._warn('the value "{0}" is invalid for {1}, which has type {2}. '
2952 "Assignment ignored."
2953 .format(v, self.name, typename[self.type]))
2956 if self.prompts == [] and not suppress_load_warnings:
2957 self.config._warn('assigning "{0}" to the symbol {1} which '
2958 'lacks prompts and thus has visibility "n". '
2959 'The assignment will have no effect.'
2960 .format(v, self.name))
2964 if self.is_choice_symbol_ and (self.type == BOOL or
2965 self.type == TRISTATE):
2966 choice = self.parent
2968 choice.user_val = self
2969 choice.user_mode = "y"
2971 choice.user_val = None
2972 choice.user_mode = "m"
2974 def _unset_user_value_no_recursive_invalidate(self):
2976 self.user_val = None
2978 if self.is_choice_symbol_:
2979 self.parent._unset_user_value()
2981 def _make_conf(self):
2982 if self.already_written:
2985 self.already_written = True
2987 # Note: write_to_conf is determined in get_value()
2988 val = self.get_value()
2989 if not self.write_to_conf:
2992 if self.type == BOOL or self.type == TRISTATE:
2993 if val == "m" or val == "y":
2994 return ["CONFIG_{0}={1}".format(self.name, val)]
2995 return ["# CONFIG_{0} is not set".format(self.name)]
2997 elif self.type == STRING:
2999 return ['CONFIG_{0}="{1}"'
3001 val.replace("\\", "\\\\").replace('"', '\\"'))]
3003 elif self.type == INT or self.type == HEX:
3004 return ["CONFIG_{0}={1}".format(self.name, val)]
3007 _internal_error('Internal error while creating .config: unknown type "{0}".'
3010 def _get_dependent(self):
3011 """Returns the set of symbols that should be invalidated if the value
3012 of the symbol changes, because they might be affected by the change.
3013 Note that this is an internal API -- it's probably of limited
3014 usefulness to clients."""
3015 if self.cached_deps is not None:
3016 return self.cached_deps
3020 self._add_dependent_ignore_siblings(res)
3021 if self.is_choice_symbol_:
3022 for s in self.parent.get_symbols():
3025 s._add_dependent_ignore_siblings(res)
3027 self.cached_deps = res
3030 def _add_dependent_ignore_siblings(self, to):
3031 """Calculating dependencies gets a bit tricky for choice items as they
3032 all depend on each other, potentially leading to infinite recursion.
3033 This helper function calculates dependencies ignoring the other symbols
3034 in the choice. It also works fine for symbols that are not choice
3038 to |= s._get_dependent()
3040 def _has_auto_menu_dep_on(self, on):
3041 """See Choice._determine_actual_symbols()."""
3042 if not isinstance(self.parent, Choice):
3043 _internal_error("Attempt to determine auto menu dependency for symbol ouside of choice.")
3045 if self.prompts == []:
3046 # If we have no prompt, use the menu dependencies instead (what was
3047 # specified with 'depends on')
3048 return self.menu_dep is not None and \
3049 self.config._expr_depends_on(self.menu_dep, on)
3051 for (_, cond_expr) in self.prompts:
3052 if self.config._expr_depends_on(cond_expr, on):
3059 """Represents a menu statement."""
3065 def get_config(self):
3066 """Return the Config instance this menu is from."""
3069 def get_visibility(self):
3070 """Returns the visibility of the menu. This also affects the visibility
3071 of subitems. See also Symbol.get_visibility()."""
3072 return self.config._eval_expr(self.dep_expr)
3074 def get_visible_if_visibility(self):
3075 """Returns the visibility the menu gets from its 'visible if'
3076 condition. "y" if the menu has no 'visible if' condition."""
3077 return self.config._eval_expr(self.visible_if_expr)
3079 def get_items(self, recursive = False):
3080 """Returns a list containing the items (symbols, menus, choice
3081 statements and comments) in in the menu, in the same order that the
3082 items appear within the menu.
3084 recursive (default: False) -- True if items contained in items within
3085 the menu should be included
3086 recursively (preorder)."""
3089 return self.block.get_items()
3092 for item in self.block.get_items():
3094 if isinstance(item, Menu):
3095 res.extend(item.get_items(True))
3096 elif isinstance(item, Choice):
3097 res.extend(item.get_items())
3100 def get_symbols(self, recursive = False):
3101 """Returns a list containing the symbols in the menu, in the same order
3102 that they appear within the menu.
3104 recursive (default: False) -- True if symbols contained in items within
3105 the menu should be included
3108 return [item for item in self.get_items(recursive) if isinstance(item, Symbol)]
3110 def get_title(self):
3111 """Returns the title text of the menu."""
3114 def get_parent(self):
3115 """Returns the menu or choice statement that contains the menu, or
3116 None if the menu is at the top level. Note that if statements are
3117 treated as syntactic sugar and do not have an explicit class
3121 def get_referenced_symbols(self, refs_from_enclosing = False):
3122 """See Symbol.get_referenced_symbols()."""
3123 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3125 def get_location(self):
3126 """Returns the location of the menu as a (filename, linenr) tuple,
3127 where filename is a string and linenr an int."""
3128 return (self.filename, self.linenr)
3131 """Returns a string containing various information about the menu."""
3132 depends_on_str = self.config._expr_val_str(self.orig_deps,
3133 "(no dependencies)")
3134 visible_if_str = self.config._expr_val_str(self.visible_if_expr,
3135 "(no dependencies)")
3137 additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
3138 "(no additional dependencies)")
3140 return _sep_lines("Menu",
3141 "Title : " + self.title,
3142 "'depends on' dependencies : " + depends_on_str,
3143 "'visible if' dependencies : " + visible_if_str,
3144 "Additional dependencies from enclosing menus and if's:",
3145 additional_deps_str,
3146 "Location: {0}:{1}".format(self.filename, self.linenr))
3153 """Menu constructor -- not intended to be called directly by
3154 kconfiglib clients."""
3161 self.dep_expr = None
3163 # Dependency expression without dependencies from enclosing menus and
3165 self.orig_deps = None
3167 # Dependencies inherited from containing menus and if's
3168 self.deps_from_containing = None
3170 # The 'visible if' expression
3171 self.visible_if_expr = None
3173 # The set of symbols referenced by this menu (see
3174 # get_referenced_symbols())
3175 self.referenced_syms = set()
3177 # Like 'referenced_syms', but includes symbols from
3178 # dependencies inherited from enclosing menus and if's
3179 self.all_referenced_syms = None
3181 self.filename = None
3184 def _make_conf(self):
3185 item_conf = self.block._make_conf()
3187 if self.config._eval_expr(self.dep_expr) != "n" and \
3188 self.config._eval_expr(self.visible_if_expr) != "n":
3189 return ["\n#\n# {0}\n#".format(self.title)] + item_conf
3192 class Choice(Item, _HasVisibility):
3194 """Represents a choice statement. A choice can be in one of three modes:
3196 "n" - The choice is not visible and no symbols can be selected.
3198 "m" - Any number of symbols can be set to "m". The rest will be "n". This
3199 is safe since potentially conflicting options don't actually get
3200 compiled into the kernel simultaneously with "m".
3202 "y" - One symbol will be "y" while the rest are "n".
3204 Only tristate choices can be in "m" mode, and the visibility of the choice
3205 is an upper bound on the mode, so that e.g. a choice that depends on a
3206 symbol with value "m" will be in "m" mode.
3208 The mode changes automatically when a value is assigned to a symbol within
3211 See Symbol.get_visibility() too."""
3217 def get_selection(self):
3218 """Returns the symbol selected (either by the user or through
3219 defaults), or None if either no symbol is selected or the mode is not
3221 if self.cached_selection is not None:
3222 if self.cached_selection == NO_SELECTION:
3224 return self.cached_selection
3226 if self.get_mode() != "y":
3227 return self._cache_ret(None)
3229 # User choice available?
3230 if self.user_val is not None and \
3231 self.user_val._get_visibility() == "y":
3232 return self._cache_ret(self.user_val)
3235 return self._cache_ret(None)
3237 return self._cache_ret(self.get_selection_from_defaults())
3239 def get_selection_from_defaults(self):
3240 """Like Choice.get_selection(), but acts as if no symbol has been
3241 selected by the user and no 'optional' flag is in effect."""
3243 if self.actual_symbols == []:
3246 for (symbol, cond_expr) in self.def_exprs:
3247 if self.config._eval_expr(cond_expr) != "n":
3248 chosen_symbol = symbol
3251 chosen_symbol = self.actual_symbols[0]
3253 # Is the chosen symbol visible?
3254 if chosen_symbol._get_visibility() != "n":
3255 return chosen_symbol
3256 # Otherwise, pick the first visible symbol
3257 for sym in self.actual_symbols:
3258 if sym._get_visibility() != "n":
3262 def get_user_selection(self):
3263 """If the choice is in "y" mode and has a user-selected symbol, returns
3264 that symbol. Otherwise, returns None."""
3265 return self.user_val
3267 def get_config(self):
3268 """Returns the Config instance this choice is from."""
3272 """For named choices, returns the name. Returns None for unnamed
3273 choices. No named choices appear anywhere in the kernel Kconfig files
3274 as of Linux 3.7.0-rc8."""
3277 def get_prompts(self):
3278 """Returns a list of prompts defined for the choice, in the order they
3279 appear in the configuration files. Returns the empty list for choices
3282 This list will have a single entry for the vast majority of choices
3283 having prompts, but having multiple prompts for a single choice is
3284 possible through having multiple 'choice' entries for it (though I'm
3285 not sure if that ever happens in practice)."""
3286 return [prompt for prompt, _ in self.orig_prompts]
3289 """Returns the help text of the choice, or None if the choice has no
3294 """Returns the type of the choice. See Symbol.get_type()."""
3297 def get_items(self):
3298 """Gets all items contained in the choice in the same order as within
3299 the configuration ("items" instead of "symbols" since choices and
3300 comments might appear within choices. This only happens in one place as
3301 of Linux 3.7.0-rc8, in drivers/usb/gadget/Kconfig)."""
3302 return self.block.get_items()
3304 def get_symbols(self):
3305 """Returns a list containing the choice's symbols.
3307 A quirk (perhaps a bug) of Kconfig is that you can put items within a
3308 choice that will not be considered members of the choice insofar as
3309 selection is concerned. This happens for example if one symbol within a
3310 choice 'depends on' the symbol preceding it, or if you put non-symbol
3311 items within choices.
3313 As of Linux 3.7.0-rc8, this seems to be used intentionally in one
3314 place: drivers/usb/gadget/Kconfig.
3316 This function returns the "proper" symbols of the choice in the order
3317 they appear in the choice, excluding such items. If you want all items
3318 in the choice, use get_items()."""
3319 return self.actual_symbols
3321 def get_parent(self):
3322 """Returns the menu or choice statement that contains the choice, or
3323 None if the choice is at the top level. Note that if statements are
3324 treated as syntactic sugar and do not have an explicit class
3328 def get_referenced_symbols(self, refs_from_enclosing = False):
3329 """See Symbol.get_referenced_symbols()."""
3330 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3332 def get_def_locations(self):
3333 """Returns a list of (filename, linenr) tuples, where filename (string)
3334 and linenr (int) represent a location where the choice is defined. For
3335 the vast majority of choices (all of them as of Linux 3.7.0-rc8) this
3336 list will only contain one element, but its possible for named choices
3337 to be defined in multiple locations."""
3338 return self.def_locations
3340 def get_visibility(self):
3341 """Returns the visibility of the choice statement: one of "n", "m" or
3342 "y". This acts as an upper limit on the mode of the choice (though bool
3343 choices can only have the mode "y"). See the class documentation for an
3344 explanation of modes."""
3345 return self._get_visibility()
3348 """Returns the mode of the choice. See the class documentation for
3349 an explanation of modes."""
3350 minimum_mode = "n" if self.optional else "m"
3351 mode = self.user_mode if self.user_mode is not None else minimum_mode
3352 mode = self.config._eval_min(mode, self._get_visibility())
3354 # Promote "m" to "y" for boolean choices
3355 if mode == "m" and self.type == BOOL:
3360 def is_optional(self):
3361 """Returns True if the symbol has the optional flag set (and so will default
3362 to "n" mode). Otherwise, returns False."""
3363 return self.optional
3366 """Returns a string containing various information about the choice
3368 return self.config._get_sym_or_choice_str(self)
3375 """Choice constructor -- not intended to be called directly by
3376 kconfiglib clients."""
3378 _HasVisibility.__init__(self)
3383 self.name = None # Yes, choices can be named
3387 self.optional = False
3390 # The prompts and default values without any dependencies from
3391 # enclosing menus or if's propagated
3393 self.orig_prompts = []
3394 self.orig_def_exprs = []
3396 # Dependencies inherited from containing menus and if's
3397 self.deps_from_containing = None
3399 # We need to filter out symbols that appear within the choice block but
3400 # are not considered choice items (see
3401 # Choice._determine_actual_symbols()) This list holds the "actual" choice
3403 self.actual_symbols = []
3405 # The set of symbols referenced by this choice (see
3406 # get_referenced_symbols())
3407 self.referenced_syms = set()
3409 # Like 'referenced_syms', but includes symbols from
3410 # dependencies inherited from enclosing menus and if's
3411 self.all_referenced_syms = set()
3413 # See Choice.get_def_locations()
3414 self.def_locations = []
3416 self.user_val = None
3417 self.user_mode = None
3419 self.cached_selection = None
3421 def _determine_actual_symbols(self):
3422 """If a symbol's visibility depends on the preceding symbol within a
3423 choice, it is no longer viewed as a choice item (quite possibly a bug,
3424 but some things consciously use it.. ugh. It stems from automatic
3425 submenu creation). In addition, it's possible to have choices and
3426 comments within choices, and those shouldn't be considered as choice
3427 items either. Only drivers/usb/gadget/Kconfig seems to depend on any of
3428 this. This method computes the "actual" items in the choice and sets
3429 the is_choice_symbol_ flag on them (retrieved via is_choice_symbol()).
3431 Don't let this scare you: an earlier version simply checked for a
3432 sequence of symbols where all symbols after the first appeared in the
3433 'depends on' expression of the first, and that worked fine. The added
3434 complexity is to be future-proof in the event that
3435 drivers/usb/gadget/Kconfig turns even more sinister. It might very well
3436 be overkilling things (especially if that file is refactored ;)."""
3438 items = self.block.get_items()
3440 # Items might depend on each other in a tree structure, so we need a
3441 # stack to keep track of the current tentative parent
3445 if not isinstance(item, Symbol):
3450 if item._has_auto_menu_dep_on(stack[-1]):
3451 # The item should not be viewed as a choice item, so don't
3452 # set item.is_choice_symbol_.
3458 item.is_choice_symbol_ = True
3459 self.actual_symbols.append(item)
3462 def _cache_ret(self, selection):
3463 # As None is used to indicate the lack of a cached value we can't use
3464 # that to cache the fact that the choice has no selection. Instead, we
3465 # use the symbolic constant NO_SELECTION.
3466 if selection is None:
3467 self.cached_selection = NO_SELECTION
3469 self.cached_selection = selection
3473 def _invalidate(self):
3474 _HasVisibility._invalidate(self)
3475 self.cached_selection = None
3477 def _unset_user_value(self):
3479 self.user_val = None
3480 self.user_mode = None
3482 def _make_conf(self):
3483 return self.block._make_conf()
3485 class Comment(Item):
3487 """Represents a comment statement."""
3493 def get_config(self):
3494 """Returns the Config instance this comment is from."""
3497 def get_visibility(self):
3498 """Returns the visibility of the comment. See also
3499 Symbol.get_visibility()."""
3500 return self.config._eval_expr(self.dep_expr)
3503 """Returns the text of the comment."""
3506 def get_parent(self):
3507 """Returns the menu or choice statement that contains the comment, or
3508 None if the comment is at the top level. Note that if statements are
3509 treated as syntactic sugar and do not have an explicit class
3513 def get_referenced_symbols(self, refs_from_enclosing = False):
3514 """See Symbol.get_referenced_symbols()."""
3515 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3517 def get_location(self):
3518 """Returns the location of the comment as a (filename, linenr) tuple,
3519 where filename is a string and linenr an int."""
3520 return (self.filename, self.linenr)
3523 """Returns a string containing various information about the comment."""
3524 dep_str = self.config._expr_val_str(self.orig_deps, "(no dependencies)")
3526 additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
3527 "(no additional dependencies)")
3529 return _sep_lines("Comment",
3530 "Text: " + str(self.text),
3531 "Dependencies: " + dep_str,
3532 "Additional dependencies from enclosing menus and if's:",
3533 additional_deps_str,
3534 "Location: {0}:{1}".format(self.filename, self.linenr))
3541 """Comment constructor -- not intended to be called directly by
3542 kconfiglib clients."""
3548 self.dep_expr = None
3550 # Dependency expression without dependencies from enclosing menus and
3552 self.orig_deps = None
3554 # Dependencies inherited from containing menus and if's
3555 self.deps_from_containing = None
3557 # The set of symbols referenced by this comment (see
3558 # get_referenced_symbols())
3559 self.referenced_syms = set()
3561 # Like 'referenced_syms', but includes symbols from
3562 # dependencies inherited from enclosing menus and if's
3563 self.all_referenced_syms = None
3565 self.filename = None
3568 def _make_conf(self):
3569 if self.config._eval_expr(self.dep_expr) != "n":
3570 return ["\n#\n# {0}\n#".format(self.text)]
3575 """Class for working with sequences in a stream-like fashion; handy for tokens."""
3577 def __init__(self, items):
3579 self.length = len(self.items)
3583 if self.i >= self.length:
3586 item = self.items[self.i]
3590 def peek_next(self):
3591 return None if self.i >= self.length else self.items[self.i]
3593 def go_to_start(self):
3596 def __getitem__(self, index):
3597 return self.items[index]
3600 return len(self.items)
3603 return self.items == []
3605 def check(self, token):
3606 """Check if the next token is 'token'. If so, remove it from the token
3607 feed and return True. Otherwise, leave it in and return False."""
3608 if self.i >= self.length:
3611 if self.items[self.i] == token:
3617 def remove_while(self, pred):
3618 while self.i < self.length and pred(self.items[self.i]):
3623 _internal_error("Attempt to move back in Feed while already at the beginning.")
3626 class _FileFeed(_Feed):
3628 """Feed subclass that keeps track of the current filename and line
3631 def __init__(self, lines, filename):
3632 self.filename = _clean_up_path(filename)
3633 _Feed.__init__(self, lines)
3635 def get_filename(self):
3636 return self.filename
3638 def get_linenr(self):
3642 # Misc. public global utility functions
3645 def tri_less(v1, v2):
3646 """Returns True if the tristate v1 is less than the tristate v2, where "n",
3647 "m" and "y" are ordered from lowest to highest. Otherwise, returns
3649 return tri_to_int[v1] < tri_to_int[v2]
3651 def tri_less_eq(v1, v2):
3652 """Returns True if the tristate v1 is less than or equal to the tristate
3653 v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
3655 return tri_to_int[v1] <= tri_to_int[v2]
3657 def tri_greater(v1, v2):
3658 """Returns True if the tristate v1 is greater than the tristate v2, where
3659 "n", "m" and "y" are ordered from lowest to highest. Otherwise, returns
3661 return tri_to_int[v1] > tri_to_int[v2]
3663 def tri_greater_eq(v1, v2):
3664 """Returns True if the tristate v1 is greater than or equal to the tristate
3665 v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
3667 return tri_to_int[v1] >= tri_to_int[v2]
3670 # Helper functions, mostly related to text processing
3673 def _strip_quotes(s, line, filename, linenr):
3674 """Removes any quotes surrounding 's' if it has them; otherwise returns 's'
3679 if s[0] == '"' or s[0] == "'":
3680 if len(s) < 2 or s[-1] != s[0]:
3682 "malformed string literal",
3688 def _indentation(line):
3689 """Returns the indentation of the line, treating tab stops as being spaced
3690 8 characters apart."""
3692 _internal_error("Attempt to take indentation of blank line.")
3698 # Go to the next tab stop
3699 indent = (indent + 8) & ~7
3703 def _deindent(line, indent):
3704 """Deindent 'line' by 'indent' spaces."""
3705 line = line.expandtabs()
3706 if len(line) <= indent:
3708 return line[indent:]
3710 def _is_base_n(s, n):
3717 def _sep_lines(*args):
3718 """Returns a string comprised of all arguments, with newlines inserted
3720 return "\n".join(args)
3723 """Returns a new string with "#" inserted before each line in 's'."""
3726 res = "".join(["#" + line for line in s.splitlines(True)])
3727 if s.endswith("\n"):
3731 def _get_lines(filename):
3732 """Returns a list of lines from 'filename', joining any line ending in \\
3733 with the following line."""
3734 with open(filename, "r") as f:
3743 if line.endswith("\\\n"):
3750 def _strip_trailing_slash(path):
3751 """Removes any trailing slash from 'path'."""
3752 return path[:-1] if path.endswith("/") else path
3754 def _clean_up_path(path):
3755 """Strips any initial "./" and trailing slash from 'path'."""
3756 if path.startswith("./"):
3758 return _strip_trailing_slash(path)
3764 class Kconfig_Syntax_Error(Exception):
3765 """Exception raised for syntax errors."""
3768 class Internal_Error(Exception):
3769 """Exception raised for internal errors."""
3772 def _tokenization_error(s, index, filename, linenr):
3773 if filename is not None:
3774 assert linenr is not None
3775 sys.stderr.write("{0}:{1}:\n".format(filename, linenr))
3777 if s.endswith("\n"):
3780 # Calculate the visual offset corresponding to index 'index' in 's'
3781 # assuming tabstops are spaced 8 characters apart
3785 vis_index = (vis_index + 8) & ~7
3789 # Don't output actual tabs to be independent of how the terminal renders
3793 raise Kconfig_Syntax_Error, (
3794 _sep_lines("Error during tokenization at location indicated by caret.\n",
3796 " " * vis_index + "^\n"))
3798 def _parse_error(s, msg, filename, linenr):
3801 if filename is not None:
3802 assert linenr is not None
3803 error_str += "{0}:{1}: ".format(filename, linenr)
3805 if s.endswith("\n"):
3808 error_str += 'Error while parsing "{0}"'.format(s) + \
3809 ("." if msg is None else ": " + msg)
3811 raise Kconfig_Syntax_Error, error_str
3813 def _internal_error(msg):
3814 msg += "\nSorry! You may want to send an email to kconfiglib@gmail.com " \
3815 "to tell me about this. Include the message above and the stack " \
3816 "trace and describe what you were doing."
3818 raise Internal_Error, msg
3823 Config._tokenize = psyco.proxy(Config._tokenize)
3824 Config._eval_expr = psyco.proxy(Config._eval_expr)
3826 _indentation = psyco.proxy(_indentation)
3827 _get_lines = psyco.proxy(_get_lines)