1 # This is Kconfiglib, a Python library for scripting, debugging, and extracting
2 # information from Kconfig-based configuration systems. To view the
7 # or, if you prefer HTML,
9 # $ pydoc -w kconfiglib
11 # The examples/ subdirectory contains examples, to be run with e.g.
13 # $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
15 # Look in testsuite.py for the test suite.
18 Kconfiglib is a Python library for scripting and extracting information from
19 Kconfig-based configuration systems. Features include the following:
21 - Symbol values and properties can be looked up and values assigned
23 - .config files can be read and written.
24 - Expressions can be evaluated in the context of a Kconfig configuration.
25 - Relations between symbols can be quickly determined, such as finding all
26 symbols that reference a particular symbol.
27 - Highly compatible with the scripts/kconfig/*conf utilities. The test suite
28 automatically compares outputs between Kconfiglib and the C implementation
29 for a large number of cases.
31 For the Linux kernel, scripts are run using
33 $ make scriptconfig SCRIPT=<path to script> [SCRIPT_ARG=<arg>]
35 Running scripts via the 'scriptconfig' target ensures that required environment
36 variables (SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly.
37 Alternative architectures can be specified like for other 'make *config'
40 $ make scriptconfig ARCH=mips SCRIPT=<path to script> [SCRIPT_ARG=<arg>]
42 The script will receive the name of the Kconfig file to load in sys.argv[1].
43 (As of Linux 3.7.0-rc8 this is always "Kconfig" from the kernel top-level
44 directory.) If an argument is provided with SCRIPT_ARG, it will appear in
47 To get an interactive Python prompt with Kconfiglib preloaded and a Config
48 object 'c' created, use
50 $ make iscriptconfig [ARCH=<architecture>]
52 Kconfiglib requires Python 2. For (i)scriptconfig the command to run the Python
53 interpreter can be passed in the environment variable PYTHONCMD (defaults to
54 'python'; PyPy works too and is a bit faster).
56 Look in the examples/ subdirectory for examples, which can be run with e.g.
58 $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
62 $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG="kernel"
64 Look in testsuite.py for the test suite.
66 Credits: Written by Ulf "Ulfalizer" Magnusson
68 Send bug reports, suggestions and other feedback to kconfiglib@gmail.com .
69 Don't wrestle with internal APIs. Tell me what you need and I might add it in a
70 safe way as a client API instead."""
72 # If you have Psyco installed (32-bit installations, Python <= 2.6 only),
73 # setting this to True (right here, not at runtime) might give a nice speedup.
74 # (22% faster for parsing arch/x86/Kconfig and 58% faster for evaluating all
75 # symbols in it without a .config on my Core Duo.)
85 """Represents a Kconfig configuration, e.g. for i386 or ARM. This is the
86 set of symbols and other items appearing in the configuration together with
87 their values. Creating any number of Config objects -- including for
88 different architectures -- is safe; Kconfiglib has no global state."""
96 base_dir = "$srctree",
97 print_warnings = True,
98 print_undef_assign = False):
99 """Creates a new Config object, representing a Kconfig configuration.
100 Raises Kconfig_Syntax_Error on syntax errors.
102 filename (default: "Kconfig") -- The base Kconfig file of the
103 configuration. For the Linux kernel, this should usually be be
104 "Kconfig" from the top-level directory, as environment
105 variables will make sure the right Kconfig is included from
106 there (usually arch/<architecture>/Kconfig). If you are using
107 kconfiglib via 'make scriptconfig' the filename of the
108 correct Kconfig will be in sys.argv[1].
110 base_dir (default: "$srctree") -- The base directory relative to which
111 'source' statements within Kconfig files will work. For the
112 Linux kernel this should be the top-level directory of the
113 kernel tree. $-references to environment variables will be
116 The environment variable 'srctree' is set by the Linux makefiles
117 to the top-level kernel directory. A default of "." would not
118 work if an alternative build directory is used.
120 print_warnings (default: True) -- Set to True if warnings related to
121 this configuration should be printed to stderr. This can
122 be changed later with Config.set_print_warnings(). It is
123 provided as a constructor argument since warnings might
124 be generated during parsing.
126 print_undef_assign (default: False) -- Set to True if informational
127 messages related to assignments to undefined symbols
128 should be printed to stderr for this configuration.
129 Can be changed later with
130 Config.set_print_undef_assign()."""
132 # The set of all symbols, indexed by name (a string)
135 # The set of all defined symbols in the configuration in the order they
136 # appear in the Kconfig files. This excludes the special symbols n, m,
137 # and y as well as symbols that are referenced but never defined.
138 self.kconfig_syms = []
140 # The set of all named choices (yes, choices can have names), indexed
142 self.named_choices = {}
144 def register_special_symbol(type, name, value):
146 sym.is_special_ = True
147 sym.is_defined_ = True
151 sym.cached_value = value
152 self.syms[name] = sym
155 # The special symbols n, m and y, used as shorthand for "n", "m" and
157 self.n = register_special_symbol(TRISTATE, "n", "n")
158 self.m = register_special_symbol(TRISTATE, "m", "m")
159 self.y = register_special_symbol(TRISTATE, "y", "y")
161 # DEFCONFIG_LIST uses this
162 register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
164 # The symbol with "option defconfig_list" set, containing a list of
165 # default .config files
166 self.defconfig_sym = None
168 # See Symbol.get_(src)arch()
169 self.arch = os.environ.get("ARCH")
170 self.srcarch = os.environ.get("SRCARCH")
172 # See Config.__init__(). We need this for get_defconfig_filename().
173 self.srctree = os.environ.get("srctree")
174 if self.srctree is None:
177 self.filename = filename
178 self.base_dir = _strip_trailing_slash(os.path.expandvars(base_dir))
180 # The 'mainmenu' text
181 self.mainmenu_text = None
183 # The filename of the most recently loaded .config file
184 self.config_filename = None
186 # The textual header of the most recently loaded .config, uncommented
187 self.config_header = None
189 self.print_warnings = print_warnings
190 self.print_undef_assign = print_undef_assign
192 # Lists containing all choices, menus and comments in the configuration
198 # For parsing routines that stop when finding a line belonging to a
199 # different construct, these holds that line and the tokenized version
200 # of that line. The purpose is to avoid having to re-tokenize the line,
201 # which is inefficient and causes problems when recording references to
204 self.end_line_tokens = None
206 # See the comment in _parse_expr().
207 self.parse_expr_cur_sym_or_choice = None
208 self.parse_expr_line = None
209 self.parse_expr_filename = None
210 self.parse_expr_linenr = None
211 self.parse_expr_transform_m = None
213 # Parse the Kconfig files
214 self.top_block = self._parse_file(filename, None, None, None)
216 # Build Symbol.dep for all symbols
219 def load_config(self, filename, replace = True):
220 """Loads symbol values from a file in the familiar .config format.
221 Equivalent to calling Symbol.set_user_value() to set each of the
224 filename -- The .config file to load. $-references to environment
225 variables will be expanded. For scripts to work even
226 when an alternative build directory is used with the
227 Linux kernel, you need to refer to the top-level kernel
228 directory with "$srctree".
230 replace (default: True) -- True if the configuration should replace
231 the old configuration; False if it should add to it."""
233 def warn_override(filename, linenr, name, old_user_val, new_user_val):
234 self._warn("overriding the value of {0}. "
235 'Old value: "{1}", new value: "{2}".'
236 .format(name, old_user_val, new_user_val),
240 filename = os.path.expandvars(filename)
242 # Put this first so that a missing file doesn't screw up our state
243 line_feeder = _FileFeed(_get_lines(filename), filename)
245 self.config_filename = filename
247 # Invalidate everything. This is usually faster than finding the
248 # minimal set of symbols that needs to be invalidated, as nearly all
249 # symbols will tend to be affected anyway.
251 self.unset_user_values()
253 self._invalidate_all()
257 self.config_header = None
259 def is_header_line(line):
260 return line.startswith("#") and \
261 not unset_re.match(line)
263 first_line = line_feeder.get_next()
265 if first_line is None:
268 if not is_header_line(first_line):
269 line_feeder.go_back()
271 self.config_header = first_line[1:]
273 # Read remaining header lines
275 line = line_feeder.get_next()
280 if not is_header_line(line):
281 line_feeder.go_back()
284 self.config_header += line[1:]
286 # Remove trailing newline
287 if self.config_header.endswith("\n"):
288 self.config_header = self.config_header[:-1]
292 filename = line_feeder.get_filename()
295 line = line_feeder.get_next()
299 linenr = line_feeder.get_linenr()
303 set_re_match = set_re.match(line)
305 name, val = set_re_match.groups()
306 # The unescaping producedure below should be safe since " can
307 # only appear as \" inside the string
308 val = _strip_quotes(val, line, filename, linenr)\
309 .replace('\\"', '"').replace("\\\\", "\\")
310 if name in self.syms:
311 sym = self.syms[name]
313 old_user_val = sym.user_val
314 if old_user_val is not None:
315 warn_override(filename, linenr, name, old_user_val, val)
317 if sym.is_choice_symbol_:
318 user_mode = sym.parent.user_mode
319 if user_mode is not None and user_mode != val:
320 self._warn("assignment to {0} changes mode of containing "
321 'choice from "{1}" to "{2}".'
322 .format(name, val, user_mode),
326 sym._set_user_value_no_invalidate(val, True)
329 self._undef_assign('attempt to assign the value "{0}" to the '
330 "undefined symbol {1}."
336 unset_re_match = unset_re.match(line)
338 name = unset_re_match.group(1)
339 if name in self.syms:
340 sym = self.syms[name]
342 old_user_val = sym.user_val
343 if old_user_val is not None:
344 warn_override(filename, linenr, name, old_user_val, "n")
346 sym._set_user_value_no_invalidate("n", True)
348 def write_config(self, filename, header = None):
349 """Writes out symbol values in the familiar .config format.
351 filename -- The filename under which to save the configuration.
353 header (default: None) -- A textual header that will appear at the
354 beginning of the file, with each line commented out
355 automatically. None means no header."""
357 # already_written is set when _make_conf() is called on a symbol, so
358 # that symbols defined in multiple locations only get one entry in the
359 # .config. We need to reset it prior to writing out a new .config.
360 for sym in self.syms.itervalues():
361 sym.already_written = False
363 with open(filename, "w") as f:
365 if header is not None:
366 f.write(_comment(header))
369 # Write configuration.
370 # (You'd think passing a list around to all the nodes and appending
371 # to it to avoid copying would be faster, but it's actually a lot
372 # slower with PyPy, and about as fast with Python. Passing the file
373 # around is slower too.)
374 f.write("\n".join(self.top_block._make_conf()))
377 def get_kconfig_filename(self):
378 """Returns the name of the (base) kconfig file this configuration was
383 """Returns the value the environment variable ARCH had at the time the
384 Config instance was created, or None if ARCH was not set. For the
385 kernel, this corresponds to the architecture being built for, with
386 values such as "i386" or "mips"."""
389 def get_srcarch(self):
390 """Returns the value the environment variable SRCARCH had at the time
391 the Config instance was created, or None if SRCARCH was not set. For
392 the kernel, this corresponds to the arch/ subdirectory containing
393 architecture-specific source code."""
396 def get_srctree(self):
397 """Returns the value the environment variable srctree had at the time
398 the Config instance was created, or None if srctree was not defined.
399 This variable points to the source directory and is used when building
400 in a separate directory."""
403 def get_config_filename(self):
404 """Returns the name of the most recently loaded configuration file, or
405 None if no configuration has been loaded."""
406 return self.config_filename
408 def get_mainmenu_text(self):
409 """Returns the text of the 'mainmenu' statement (with $-references to
410 symbols replaced by symbol values), or None if the configuration has no
411 'mainmenu' statement."""
412 return None if self.mainmenu_text is None else \
413 self._expand_sym_refs(self.mainmenu_text)
415 def get_defconfig_filename(self):
416 """Returns the name of the defconfig file, which is the first existing
417 file in the list given in a symbol having 'option defconfig_list' set.
418 $-references to symbols will be expanded ("$FOO bar" -> "foo bar" if
419 FOO has the value "foo"). Returns None in case of no defconfig file.
420 Setting 'option defconfig_list' on multiple symbols currently results
421 in undefined behavior.
423 If the environment variable 'srctree' was set when the Config was
424 created, get_defconfig_filename() will first look relative to that
425 directory before looking in the current directory; see
426 Config.__init__()."""
428 if self.defconfig_sym is None:
431 for (filename, cond_expr) in self.defconfig_sym.def_exprs:
432 if self._eval_expr(cond_expr) == "y":
433 filename = self._expand_sym_refs(filename)
435 # We first look in $srctree. os.path.join() won't work here as
436 # an absolute path in filename would override $srctree.
437 srctree_filename = os.path.normpath(self.srctree + "/" + filename)
438 if os.path.exists(srctree_filename):
439 return srctree_filename
441 if os.path.exists(filename):
446 def get_symbol(self, name):
447 """Returns the symbol with name 'name', or None if no such symbol
448 appears in the configuration. An alternative shorthand is conf[name],
449 where conf is a Config instance, though that will instead raise
450 KeyError if the symbol does not exist."""
451 return self.syms.get(name)
453 def get_top_level_items(self):
454 """Returns a list containing the items (symbols, menus, choice
455 statements and comments) at the top level of the configuration -- that
456 is, all items that do not appear within a menu or choice. The items
457 appear in the same order as within the configuration."""
458 return self.top_block.get_items()
460 def get_symbols(self, all_symbols = True):
461 """Returns a list of symbols from the configuration. An alternative for
462 iterating over all defined symbols (in the order of definition) is
467 which relies on Config implementing __iter__() and is equivalent to
469 for sym in config.get_symbols(False):
472 all_symbols (default: True) -- If True, all symbols - including special
473 and undefined symbols - will be included in the result, in
474 an undefined order. If False, only symbols actually defined
475 and not merely referred to in the configuration will be
476 included in the result, and will appear in the order that
477 they are defined within the Kconfig configuration files."""
478 return self.syms.values() if all_symbols else self.kconfig_syms
480 def get_choices(self):
481 """Returns a list containing all choice statements in the
482 configuration, in the order they appear in the Kconfig files."""
486 """Returns a list containing all menus in the configuration, in the
487 order they appear in the Kconfig files."""
490 def get_comments(self):
491 """Returns a list containing all comments in the configuration, in the
492 order they appear in the Kconfig files."""
496 """Returns the value of the expression 's' -- where 's' is represented
497 as a string -- in the context of the configuration. Raises
498 Kconfig_Syntax_Error if syntax errors are detected in 's'.
500 For example, if FOO and BAR are tristate symbols at least one of which
501 has the value "y", then config.eval("y && (FOO || BAR)") => "y"
503 This functions always yields a tristate value. To get the value of
504 non-bool, non-tristate symbols, use Symbol.get_value().
506 The result of this function is consistent with how evaluation works for
507 conditional expressions in the configuration as well as in the C
508 implementation. "m" and m are rewritten as '"m" && MODULES' and 'm &&
509 MODULES', respectively, and a result of "m" will get promoted to "y" if
510 we're running without modules."""
511 return self._eval_expr(self._parse_expr(self._tokenize(s, True), # Feed
512 None, # Current symbol or choice
515 def get_config_header(self):
516 """Returns the (uncommented) textual header of the .config file most
517 recently loaded with load_config(). Returns None if no .config file has
518 been loaded or if the most recently loaded .config file has no header.
519 The header comprises all lines up to but not including the first line
522 1. Does not start with "#"
523 2. Has the form "# CONFIG_FOO is not set."
525 return self.config_header
527 def get_base_dir(self):
528 """Returns the base directory relative to which 'source' statements
529 will work, passed as an argument to Config.__init__()."""
532 def set_print_warnings(self, print_warnings):
533 """Determines whether warnings related to this configuration (for
534 things like attempting to assign illegal values to symbols with
535 Symbol.set_user_value()) should be printed to stderr.
537 print_warnings -- True if warnings should be
538 printed, otherwise False."""
539 self.print_warnings = print_warnings
541 def set_print_undef_assign(self, print_undef_assign):
542 """Determines whether informational messages related to assignments to
543 undefined symbols should be printed to stderr for this configuration.
545 print_undef_assign -- If True, such messages will be printed."""
546 self.print_undef_assign = print_undef_assign
548 def __getitem__(self, key):
549 """Returns the symbol with name 'name'. Raises KeyError if the symbol
550 does not appear in the configuration."""
551 return self.syms[key]
554 """Convenience function for iterating over the set of all defined
555 symbols in the configuration, used like
560 The iteration happens in the order of definition within the Kconfig
561 configuration files. Symbols only referred to but not defined will not
562 be included, nor will the special symbols n, m, and y. If you want to
563 include such symbols as well, see config.get_symbols()."""
564 return iter(self.kconfig_syms)
566 def unset_user_values(self):
567 """Resets the values of all symbols, as if Config.load_config() or
568 Symbol.set_user_value() had never been called."""
569 for sym in self.syms.itervalues():
570 sym._unset_user_value_no_recursive_invalidate()
573 """Returns a string containing various information about the Config."""
574 return _sep_lines("Configuration",
575 "File : " + self.filename,
576 "Base directory : " + self.base_dir,
577 "Value of $ARCH at creation time : " +
578 ("(not set)" if self.arch is None else self.arch),
579 "Value of $SRCARCH at creation time : " +
580 ("(not set)" if self.srcarch is None else self.srcarch),
581 "Source tree (derived from $srctree;",
582 "defaults to '.' if $srctree isn't set) : " + self.srctree,
583 "Most recently loaded .config : " +
584 ("(no .config loaded)" if self.config_filename is None else
585 self.config_filename),
586 "Print warnings : " +
587 bool_str[self.print_warnings],
588 "Print assignments to undefined symbols : " +
589 bool_str[self.print_undef_assign])
596 def _invalidate_all(self):
597 for sym in self.syms.itervalues():
605 """Returns a _Feed instance containing tokens derived from the string
606 's'. Registers any new symbols encountered (via _sym_lookup()).
608 (I experimented with a pure regular expression implementation, but it
609 came out slower, less readable, and wouldn't have been as flexible.)
611 for_eval -- True when parsing an expression for a call to
612 Config.eval(), in which case we should not treat the first
613 token specially nor register new symbols."""
615 if s == "" or s[0] == "#":
619 i = 0 # The current index in the string being tokenized
620 previous = None # The previous token seen
623 # The initial word on a line is parsed specially. Let
624 # command_chars = [A-Za-z0-9_]. Then
625 # - leading non-command_chars characters on the line are ignored, and
626 # - the first token consists the following one or more command_chars
628 # This is why things like "----help--" are accepted.
630 initial_token_match = initial_token_re.match(s)
631 if initial_token_match is None:
633 # The current index in the string being tokenized
634 i = initial_token_match.end()
636 keyword = keywords.get(initial_token_match.group(1))
638 # We expect a keyword as the first token
639 _tokenization_error(s, len(s), filename, linenr)
640 if keyword == T_HELP:
641 # Avoid junk after "help", e.g. "---", being registered as a
643 return _Feed([T_HELP])
647 # _tokenize() is a hotspot during parsing, and this speeds things up a
650 append = tokens.append
652 # Main tokenization loop. (Handles tokens past the first one.)
654 # Test for an identifier/keyword preceded by whitespace first; this
655 # is the most common case.
656 id_keyword_match = id_keyword_re.match(s, i)
658 # We have an identifier or keyword. The above also stripped any
660 name = id_keyword_match.group(1)
662 i = id_keyword_match.end()
665 keyword = keywords.get(name)
666 if keyword is not None:
668 # What would ordinarily be considered a name is treated as a
669 # string after certain tokens.
670 elif previous in string_lex:
673 # We're dealing with a symbol. _sym_lookup() will take care
674 # of allocating a new Symbol instance if it's the first
676 sym = self._sym_lookup(name, not for_eval)
678 if previous == T_CONFIG or previous == T_MENUCONFIG:
679 # If the previous token is T_(MENU)CONFIG
680 # ("(menu)config"), we're tokenizing the first line of
681 # a symbol definition, and should remember this as a
682 # location where the symbol is defined.
683 sym.def_locations.append((filename, linenr))
685 # Otherwise, it's a reference to the symbol
686 sym.ref_locations.append((filename, linenr))
691 # This restrips whitespace that could have been stripped in the
692 # regex above, but it's worth it since identifiers/keywords are
701 # String literal (constant symbol)
702 if c == '"' or c == "'":
706 # Slow path: This could probably be sped up, but it's a
707 # very unusual case anyway.
712 _tokenization_error(s, strlen, filename,
719 _tokenization_error(s, strlen, filename,
729 # Fast path: If the string contains no backslashes (almost
730 # always) we can simply look for the matching quote.
733 _tokenization_error(s, strlen, filename, linenr)
739 # Invalid characters are ignored
742 # Invalid characters are ignored
750 # Invalid characters are ignored
753 # Invalid characters are ignored
761 _tokenization_error(s, strlen, filename, linenr)
778 append(T_CLOSE_PAREN)
785 # Invalid characters are ignored
789 previous = tokens[-1]
797 # Expression grammar:
800 # <symbol> '=' <symbol>
801 # <symbol> '!=' <symbol>
807 def _parse_expr(self,
814 """Parse an expression from the tokens in 'feed' using a simple
815 top-down approach. The result has the form (<operator>, <list
816 containing parsed operands>).
818 feed -- _Feed instance containing the tokens for the expression.
820 cur_sym_or_choice -- The symbol or choice currently being parsed, or
821 None if we're not parsing a symbol or choice.
822 Used for recording references to symbols.
824 line -- The line containing the expression being parsed.
826 filename (default: None) -- The file containing the expression.
828 linenr (default: None) -- The line number containing the expression.
830 transform_m (default: False) -- Determines if 'm' should be rewritten to
831 'm && MODULES' -- see
832 parse_val_and_cond()."""
834 # Use instance variables to avoid having to pass these as arguments
835 # through the top-down parser in _parse_expr_2(), which is tedious and
836 # obfuscates the code. A profiler run shows no noticeable performance
838 self.parse_expr_cur_sym_or_choice = cur_sym_or_choice
839 self.parse_expr_line = line
840 self.parse_expr_filename = filename
841 self.parse_expr_linenr = linenr
842 self.parse_expr_transform_m = transform_m
844 return self._parse_expr_2(feed)
846 def _parse_expr_2(self, feed):
847 or_terms = [self._parse_or_term(feed)]
848 # Keep parsing additional terms while the lookahead is '||'
849 while feed.check(T_OR):
850 or_terms.append(self._parse_or_term(feed))
852 return or_terms[0] if len(or_terms) == 1 else (OR, or_terms)
854 def _parse_or_term(self, feed):
855 and_terms = [self._parse_factor(feed)]
856 # Keep parsing additional terms while the lookahead is '&&'
857 while feed.check(T_AND):
858 and_terms.append(self._parse_factor(feed))
860 return and_terms[0] if len(and_terms) == 1 else (AND, and_terms)
862 def _parse_factor(self, feed):
863 if feed.check(T_OPEN_PAREN):
864 expr_parse = self._parse_expr_2(feed)
866 if not feed.check(T_CLOSE_PAREN):
867 _parse_error(self.parse_expr_line,
868 "missing end parenthesis.",
869 self.parse_expr_filename,
870 self.parse_expr_linenr)
874 if feed.check(T_NOT):
875 return (NOT, self._parse_factor(feed))
877 sym_or_string = feed.get_next()
879 if not isinstance(sym_or_string, (Symbol, str)):
880 _parse_error(self.parse_expr_line,
881 "malformed expression.",
882 self.parse_expr_filename,
883 self.parse_expr_linenr)
885 if self.parse_expr_cur_sym_or_choice is not None and \
886 isinstance(sym_or_string, Symbol):
887 self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string)
889 next_token = feed.peek_next()
891 # For conditional expressions ('depends on <expr>', '... if <expr>',
892 # etc.), "m" and m are rewritten to "m" && MODULES.
893 if next_token != T_EQUAL and next_token != T_UNEQUAL:
894 if self.parse_expr_transform_m and (sym_or_string is self.m or
895 sym_or_string == "m"):
896 return (AND, ["m", self._sym_lookup("MODULES")])
899 relation = EQUAL if (feed.get_next() == T_EQUAL) else UNEQUAL
900 sym_or_string_2 = feed.get_next()
902 if self.parse_expr_cur_sym_or_choice is not None and \
903 isinstance(sym_or_string_2, Symbol):
904 self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string_2)
906 if sym_or_string is self.m:
909 if sym_or_string_2 is self.m:
910 sym_or_string_2 = "m"
912 return (relation, sym_or_string, sym_or_string_2)
914 def _parse_file(self, filename, parent, deps, visible_if_deps, res = None):
915 """Parse the Kconfig file 'filename'. The result is a _Block with all
916 items from the file. See _parse_block() for the meaning of the
918 line_feeder = _FileFeed(_get_lines(filename), filename)
919 return self._parse_block(line_feeder, None, parent, deps, visible_if_deps, res)
921 def _parse_block(self, line_feeder, end_marker, parent, deps,
922 visible_if_deps = None, res = None):
923 """Parses a block, which is the contents of either a file or an if,
924 menu, or choice statement. The result is a _Block with the items from
927 end_marker -- The token that ends the block, e.g. T_ENDIF ("endif") for
928 if's. None for files.
930 parent -- The enclosing menu, choice or if, or None if we're at the top
933 deps -- Dependencies from enclosing menus, choices and if's.
935 visible_if_deps (default: None) -- 'visible if' dependencies from
938 res (default: None) -- The _Block to add items to. If None, a new
939 _Block is created to hold the items."""
941 block = _Block() if res is None else res
943 filename = line_feeder.get_filename()
947 # Do we already have a tokenized line that we determined wasn't
948 # part of whatever we were parsing earlier? See comment in
950 if self.end_line is not None:
951 assert self.end_line_tokens is not None
952 tokens = self.end_line_tokens
956 linenr = line_feeder.get_linenr()
959 self.end_line_tokens = None
962 line = line_feeder.get_next()
964 if end_marker is not None:
965 raise Kconfig_Syntax_Error, (
966 "Unexpected end of file {0}."
967 .format(line_feeder.get_filename()))
970 linenr = line_feeder.get_linenr()
972 tokens = self._tokenize(line, False, filename, linenr)
974 if tokens.is_empty():
977 t0 = tokens.get_next()
979 # Have we reached the end of the block?
983 if t0 == T_CONFIG or t0 == T_MENUCONFIG:
984 # The tokenizer will automatically allocate a new Symbol object
985 # for any new names it encounters, so we don't need to worry
987 sym = tokens.get_next()
989 # Symbols defined in multiple places get the parent of their
990 # first definition. However, for symbols whose parents are choice
991 # statements, the choice statement takes precedence.
992 if not sym.is_defined_ or isinstance(parent, Choice):
995 sym.is_defined_ = True
997 self.kconfig_syms.append(sym)
1000 self._parse_properties(line_feeder, sym, deps, visible_if_deps)
1004 self.menus.append(menu)
1006 menu.parent = parent
1007 menu.title = tokens.get_next()
1009 menu.filename = filename
1010 menu.linenr = linenr
1012 # Parse properties and contents
1013 self._parse_properties(line_feeder, menu, deps, visible_if_deps)
1014 menu.block = self._parse_block(line_feeder,
1018 _make_and(visible_if_deps,
1019 menu.visible_if_expr))
1021 block.add_item(menu)
1024 # If statements are treated as syntactic sugar for adding
1025 # dependencies to enclosed items and do not have an explicit
1026 # object representation.
1028 dep_expr = self._parse_expr(tokens, None, line, filename, linenr)
1029 self._parse_block(line_feeder,
1032 _make_and(dep_expr, deps),
1034 block) # Add items to the same block
1036 elif t0 == T_CHOICE:
1037 # We support named choices
1038 already_defined = False
1040 if len(tokens) > 1 and isinstance(tokens[1], str):
1042 already_defined = name in self.named_choices
1045 choice = self.named_choices[name]
1048 self.choices.append(choice)
1049 if name is not None:
1051 self.named_choices[name] = choice
1053 choice.config = self
1054 choice.parent = parent
1056 choice.def_locations.append((filename, linenr))
1058 # Parse properties and contents
1059 self._parse_properties(line_feeder, choice, deps, visible_if_deps)
1060 choice.block = self._parse_block(line_feeder,
1066 choice._determine_actual_symbols()
1068 # If no type is set for the choice, its type is that of the first
1070 if choice.type == UNKNOWN:
1071 for item in choice.get_symbols():
1072 if item.type != UNKNOWN:
1073 choice.type = item.type
1076 # Each choice item of UNKNOWN type gets the type of the choice
1077 for item in choice.get_symbols():
1078 if item.type == UNKNOWN:
1079 item.type = choice.type
1081 # For named choices defined in multiple locations, only record
1082 # at the first definition
1083 if not already_defined:
1084 block.add_item(choice)
1086 elif t0 == T_COMMENT:
1088 comment.config = self
1089 comment.parent = parent
1091 comment.filename = filename
1092 comment.linenr = linenr
1094 comment.text = tokens.get_next()
1095 self._parse_properties(line_feeder, comment, deps, visible_if_deps)
1097 block.add_item(comment)
1098 self.comments.append(comment)
1100 elif t0 == T_SOURCE:
1101 kconfig_file = tokens.get_next()
1102 exp_kconfig_file = self._expand_sym_refs(kconfig_file)
1103 f = os.path.join(self.base_dir, exp_kconfig_file)
1105 if not os.path.exists(f):
1106 raise IOError, ('{0}:{1}: sourced file "{2}" (expands to\n'
1107 '"{3}") not found. Perhaps base_dir\n'
1108 '(argument to Config.__init__(), currently\n'
1109 '"{4}") is set to the wrong value.'
1116 # Add items to the same block
1117 self._parse_file(f, parent, deps, visible_if_deps, block)
1119 elif t0 == T_MAINMENU:
1120 text = tokens.get_next()
1122 if self.mainmenu_text is not None:
1123 self._warn("overriding 'mainmenu' text. "
1124 'Old value: "{0}", new value: "{1}".'
1125 .format(self.mainmenu_text, text),
1129 self.mainmenu_text = text
1132 _parse_error(line, "unrecognized construct.", filename, linenr)
1134 def _parse_properties(self, line_feeder, stmt, deps, visible_if_deps):
1135 """Parsing of properties for symbols, menus, choices, and comments."""
1137 def parse_val_and_cond(tokens, line, filename, linenr):
1138 """Parses '<expr1> if <expr2>' constructs, where the 'if' part is
1139 optional. Returns a tuple containing the parsed expressions, with
1140 None as the second element if the 'if' part is missing."""
1141 val = self._parse_expr(tokens, stmt, line, filename, linenr, False)
1143 if tokens.check(T_IF):
1144 return (val, self._parse_expr(tokens, stmt, line, filename, linenr))
1148 # In case the symbol is defined in multiple locations, we need to
1149 # remember what prompts, defaults, and selects are new for this
1150 # definition, as "depends on" should only apply to the local
1156 # Dependencies from 'depends on' statements
1157 depends_on_expr = None
1160 line = line_feeder.get_next()
1164 filename = line_feeder.get_filename()
1165 linenr = line_feeder.get_linenr()
1167 tokens = self._tokenize(line, False, filename, linenr)
1169 if tokens.is_empty():
1172 t0 = tokens.get_next()
1175 # Find first non-empty line and get its indentation
1177 line_feeder.remove_while(str.isspace)
1178 line = line_feeder.get_next()
1184 indent = _indentation(line)
1186 # If the first non-empty lines has zero indent, there is no
1190 line_feeder.go_back()
1193 help_lines = [_deindent(line, indent)]
1195 # The help text goes on till the first non-empty line with less
1198 line = line_feeder.get_next()
1199 if (line is None) or \
1200 (not line.isspace() and _indentation(line) < indent):
1201 stmt.help = "".join(help_lines)
1204 help_lines.append(_deindent(line, indent))
1209 line_feeder.go_back()
1211 elif t0 == T_PROMPT:
1212 # 'prompt' properties override each other within a single
1213 # definition of a symbol, but additional prompts can be added
1214 # by defining the symbol multiple times; hence 'new_prompt'
1215 # instead of 'prompt'.
1216 new_prompt = parse_val_and_cond(tokens, line, filename, linenr)
1218 elif t0 == T_DEFAULT:
1219 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1221 elif t0 == T_DEPENDS:
1222 if not tokens.check(T_ON):
1223 _parse_error(line, 'expected "on" after "depends".', filename, linenr)
1225 parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)
1227 if isinstance(stmt, (Menu, Comment)):
1228 stmt.dep_expr = _make_and(stmt.dep_expr, parsed_deps)
1230 depends_on_expr = _make_and(depends_on_expr, parsed_deps)
1232 elif t0 == T_VISIBLE:
1233 if not tokens.check(T_IF):
1234 _parse_error(line, 'expected "if" after "visible".', filename, linenr)
1235 if not isinstance(stmt, Menu):
1237 "'visible if' is only valid for menus.",
1241 parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)
1242 stmt.visible_if_expr = _make_and(stmt.visible_if_expr, parsed_deps)
1244 elif t0 == T_SELECT:
1245 target = tokens.get_next()
1247 stmt.referenced_syms.add(target)
1248 stmt.selected_syms.add(target)
1250 if tokens.check(T_IF):
1251 new_selects.append((target,
1252 self._parse_expr(tokens, stmt, line, filename, linenr)))
1254 new_selects.append((target, None))
1256 elif t0 in (T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING):
1257 stmt.type = token_to_type[t0]
1260 new_prompt = parse_val_and_cond(tokens, line, filename, linenr)
1263 lower = tokens.get_next()
1264 upper = tokens.get_next()
1265 stmt.referenced_syms.add(lower)
1266 stmt.referenced_syms.add(upper)
1268 if tokens.check(T_IF):
1269 stmt.ranges.append((lower, upper,
1270 self._parse_expr(tokens, stmt, line, filename, linenr)))
1272 stmt.ranges.append((lower, upper, None))
1274 elif t0 == T_DEF_BOOL:
1278 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1280 elif t0 == T_DEF_TRISTATE:
1281 stmt.type = TRISTATE
1284 new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))
1286 elif t0 == T_OPTIONAL:
1287 if not isinstance(stmt, Choice):
1289 '"optional" is only valid for choices.',
1292 stmt.optional = True
1294 elif t0 == T_OPTION:
1295 if tokens.check(T_ENV) and tokens.check(T_EQUAL):
1296 env_var = tokens.get_next()
1298 stmt.is_special_ = True
1299 stmt.is_from_env = True
1301 if env_var not in os.environ:
1303 The symbol {0} references the non-existent environment variable {1} and will
1304 get the empty string as its value.
1306 If you're using kconfiglib via 'make (i)scriptconfig' it should have set up the
1307 environment correctly for you. If you still got this message, that might be an
1308 error, and you should e-mail kconfiglib@gmail.com.
1309 .""" .format(stmt.name, env_var),
1313 stmt.cached_value = ""
1315 stmt.cached_value = os.environ[env_var]
1317 elif tokens.check(T_DEFCONFIG_LIST):
1318 self.defconfig_sym = stmt
1320 elif tokens.check(T_MODULES):
1321 self._warn("the 'modules' option is not supported. "
1322 "Let me know if this is a problem for you; "
1323 "it shouldn't be that hard to implement.",
1328 _parse_error(line, "unrecognized option.", filename, linenr)
1331 # See comment in Config.__init__()
1332 self.end_line = line
1333 self.end_line_tokens = tokens
1336 # Propagate dependencies from enclosing menus and if's.
1338 # For menus and comments..
1339 if isinstance(stmt, (Menu, Comment)):
1340 stmt.orig_deps = stmt.dep_expr
1341 stmt.deps_from_containing = deps
1342 stmt.dep_expr = _make_and(stmt.dep_expr, deps)
1344 stmt.all_referenced_syms = \
1345 stmt.referenced_syms | _get_expr_syms(deps)
1347 # For symbols and choices..
1350 # See comment for 'menu_dep'
1351 stmt.menu_dep = depends_on_expr
1353 # Propagate dependencies specified with 'depends on' to any new
1354 # default expressions, prompts, and selections. ("New" since a
1355 # symbol might be defined in multiple places and the dependencies
1356 # should only apply to the local definition.)
1358 new_def_exprs = [(val_expr, _make_and(cond_expr, depends_on_expr))
1359 for (val_expr, cond_expr) in new_def_exprs]
1361 new_selects = [(target, _make_and(cond_expr, depends_on_expr))
1362 for (target, cond_expr) in new_selects]
1364 if new_prompt is not None:
1365 prompt, cond_expr = new_prompt
1367 # 'visible if' dependencies from enclosing menus get propagated
1369 if visible_if_deps is not None:
1370 cond_expr = _make_and(cond_expr, visible_if_deps)
1372 new_prompt = (prompt, _make_and(cond_expr, depends_on_expr))
1374 # We save the original expressions -- before any menu and if
1375 # conditions have been propagated -- so these can be retrieved
1378 stmt.orig_def_exprs.extend(new_def_exprs)
1379 if new_prompt is not None:
1380 stmt.orig_prompts.append(new_prompt)
1382 # Only symbols can select
1383 if isinstance(stmt, Symbol):
1384 stmt.orig_selects.extend(new_selects)
1386 # Save dependencies from enclosing menus and if's
1387 stmt.deps_from_containing = deps
1389 # The set of symbols referenced directly by the symbol/choice plus
1390 # all symbols referenced by enclosing menus and if's.
1391 stmt.all_referenced_syms = \
1392 stmt.referenced_syms | _get_expr_syms(deps)
1394 # Propagate dependencies from enclosing menus and if's
1396 stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
1397 for (val_expr, cond_expr) in new_def_exprs])
1399 for (target, cond) in new_selects:
1400 target.rev_dep = _make_or(target.rev_dep,
1402 _make_and(cond, deps)))
1404 if new_prompt is not None:
1405 prompt, cond_expr = new_prompt
1406 stmt.prompts.append((prompt, _make_and(cond_expr, deps)))
1409 # Symbol table manipulation
1412 def _sym_lookup(self, name, add_sym_if_not_exists = True):
1413 """Fetches the symbol 'name' from the symbol table, optionally adding
1414 it if it does not exist (this is usually what we want)."""
1415 if name in self.syms:
1416 return self.syms[name]
1419 new_sym.config = self
1422 if add_sym_if_not_exists:
1423 self.syms[name] = new_sym
1425 # This warning is generated while evaluating an expression
1426 # containing undefined symbols using Config.eval()
1427 self._warn("no symbol {0} in configuration".format(name))
1432 # Evaluation of symbols and expressions
1435 def _eval_expr(self, expr):
1436 """Evaluates an expression and returns one of the tristate values "n",
1438 res = self._eval_expr_2(expr)
1440 # Promote "m" to "y" if we're running without modules. Internally, "m"
1441 # is often rewritten to "m" && MODULES by both the C implementation and
1442 # kconfiglib, which takes care of cases where "m" should be false if
1443 # we're running without modules.
1444 if res == "m" and not self._has_modules():
1449 def _eval_expr_2(self, expr):
1453 if isinstance(expr, Symbol):
1454 # Non-bool/tristate symbols are always "n" in a tristate sense,
1455 # regardless of their value
1456 if expr.type != BOOL and expr.type != TRISTATE:
1458 return expr.get_value()
1460 if isinstance(expr, str):
1461 return expr if (expr == "y" or expr == "m") else "n"
1463 first_expr = expr[0]
1465 if first_expr == OR:
1468 for subexpr in expr[1]:
1469 ev = self._eval_expr_2(subexpr)
1471 # Return immediately upon discovering a "y" term
1478 # 'res' is either "n" or "m" here; we already handled the
1479 # short-circuiting "y" case in the loop.
1482 if first_expr == AND:
1485 for subexpr in expr[1]:
1486 ev = self._eval_expr_2(subexpr)
1488 # Return immediately upon discovering an "n" term
1495 # 'res' is either "m" or "y" here; we already handled the
1496 # short-circuiting "n" case in the loop.
1499 if first_expr == NOT:
1500 ev = self._eval_expr_2(expr[1])
1505 return "y" if (ev == "n") else "m"
1507 if first_expr == EQUAL:
1508 return "y" if (self._get_str_value(expr[1]) ==
1509 self._get_str_value(expr[2])) else "n"
1511 if first_expr == UNEQUAL:
1512 return "y" if (self._get_str_value(expr[1]) !=
1513 self._get_str_value(expr[2])) else "n"
1515 _internal_error("Internal error while evaluating expression: "
1516 "unknown operation {0}.".format(first_expr))
1518 def _get_str_value(self, obj):
1519 if isinstance(obj, str):
1522 return obj.get_value()
1524 def _eval_min(self, e1, e2):
1525 e1_eval = self._eval_expr(e1)
1526 e2_eval = self._eval_expr(e2)
1528 return e1_eval if tri_less(e1_eval, e2_eval) else e2_eval
1530 def _eval_max(self, e1, e2):
1531 e1_eval = self._eval_expr(e1)
1532 e2_eval = self._eval_expr(e2)
1534 return e1_eval if tri_greater(e1_eval, e2_eval) else e2_eval
1537 # Methods related to the MODULES symbol
1540 def _has_modules(self):
1541 modules_sym = self.syms.get("MODULES")
1542 return (modules_sym is not None) and (modules_sym.get_value() == "y")
1545 # Dependency tracking
1548 def _build_dep(self):
1549 """Populates the Symbol.dep sets, linking the symbol to the symbols
1550 that immediately depend on it in the sense that changing the value of
1551 the symbol might affect the values of those other symbols. This is used
1552 for caching/invalidation purposes. The calculated sets might be larger
1553 than necessary as we don't do any complicated analysis of the
1555 for sym in self.syms.itervalues():
1558 # Adds 'sym' as a directly dependent symbol to all symbols that appear
1559 # in the expression 'e'
1560 def add_expr_deps(e, sym):
1561 for s in _get_expr_syms(e):
1564 # The directly dependent symbols of a symbol are:
1565 # - Any symbols whose prompts, default values, rev_dep (select
1566 # condition), or ranges depend on the symbol
1567 # - Any symbols that belong to the same choice statement as the symbol
1568 # (these won't be included in 'dep' as that makes the dependency
1569 # graph unwieldy, but Symbol._get_dependent() will include them)
1570 # - Any symbols in a choice statement that depends on the symbol
1571 for sym in self.syms.itervalues():
1572 for (_, e) in sym.prompts:
1573 add_expr_deps(e, sym)
1575 for (v, e) in sym.def_exprs:
1576 add_expr_deps(v, sym)
1577 add_expr_deps(e, sym)
1579 add_expr_deps(sym.rev_dep, sym)
1581 for (l, u, e) in sym.ranges:
1582 add_expr_deps(l, sym)
1583 add_expr_deps(u, sym)
1584 add_expr_deps(e, sym)
1586 if sym.is_choice_symbol_:
1589 for (_, e) in choice.prompts:
1590 add_expr_deps(e, sym)
1592 for (_, e) in choice.def_exprs:
1593 add_expr_deps(e, sym)
1595 def _expr_val_str(self, expr, no_value_str = "(none)", get_val_instead_of_eval = False):
1596 # Since values are valid expressions, _expr_to_str() will get a nice
1597 # string representation for those as well.
1602 if get_val_instead_of_eval:
1603 if isinstance(expr, str):
1604 return _expr_to_str(expr)
1605 val = expr.get_value()
1607 val = self._eval_expr(expr)
1609 return "{0} (value: {1})".format(_expr_to_str(expr), _expr_to_str(val))
1611 def _expand_sym_refs(self, s):
1612 """Expands $-references to symbols in 's' to symbol values, or to the
1613 empty string for undefined symbols."""
1616 sym_ref_re_match = sym_ref_re.search(s)
1617 if sym_ref_re_match is None:
1620 sym_name = sym_ref_re_match.group(0)[1:]
1621 sym = self.syms.get(sym_name)
1622 expansion = "" if sym is None else sym.get_value()
1624 s = s[:sym_ref_re_match.start()] + \
1626 s[sym_ref_re_match.end():]
1628 def _get_sym_or_choice_str(self, sc):
1629 """Symbols and choices have many properties in common, so we factor out
1630 common __str__() stuff here. "sc" is short for "symbol or choice"."""
1632 # As we deal a lot with string representations here, use some
1633 # convenient shorthand:
1637 # Common symbol/choice properties
1640 user_value_str = "(no user value)" if sc.user_val is None else s(sc.user_val)
1642 visibility_str = s(sc.get_visibility())
1644 # Build prompts string
1645 if sc.prompts == []:
1646 prompts_str = " (no prompts)"
1648 prompts_str_rows = []
1650 for (prompt, cond_expr) in sc.orig_prompts:
1651 if cond_expr is None:
1652 prompts_str_rows.append(' "{0}"'.format(prompt))
1654 prompts_str_rows.append(' "{0}" if '.format(prompt) +
1655 self._expr_val_str(cond_expr))
1657 prompts_str = "\n".join(prompts_str_rows)
1659 # Build locations string
1660 if sc.def_locations == []:
1661 locations_str = "(no locations)"
1663 locations_str = " ".join(["{0}:{1}".format(filename, linenr) for
1664 (filename, linenr) in sc.def_locations])
1666 # Build additional-dependencies-from-menus-and-if's string
1667 additional_deps_str = " " + self._expr_val_str(sc.deps_from_containing,
1668 "(no additional dependencies)")
1671 # Symbol-specific stuff
1674 if isinstance(sc, Symbol):
1676 # Build value string
1677 value_str = s(sc.get_value())
1679 # Build ranges string
1680 if isinstance(sc, Symbol):
1682 ranges_str = " (no ranges)"
1684 ranges_str_rows = []
1686 for (l, u, cond_expr) in sc.ranges:
1687 if cond_expr is None:
1688 ranges_str_rows.append(" [{0}, {1}]".format(s(l), s(u)))
1690 ranges_str_rows.append(" [{0}, {1}] if {2}"
1691 .format(s(l), s(u), self._expr_val_str(cond_expr)))
1693 ranges_str = "\n".join(ranges_str_rows)
1695 # Build default values string
1696 if sc.def_exprs == []:
1697 defaults_str = " (no default values)"
1699 defaults_str_rows = []
1701 for (val_expr, cond_expr) in sc.orig_def_exprs:
1702 row_str = " " + self._expr_val_str(val_expr, "(none)", sc.type == STRING)
1703 defaults_str_rows.append(row_str)
1704 defaults_str_rows.append(" Condition: " + self._expr_val_str(cond_expr))
1706 defaults_str = "\n".join(defaults_str_rows)
1708 # Build selects string
1709 if sc.orig_selects == []:
1710 selects_str = " (no selects)"
1712 selects_str_rows = []
1714 for (target, cond_expr) in sc.orig_selects:
1715 if cond_expr is None:
1716 selects_str_rows.append(" {0}".format(target.name))
1718 selects_str_rows.append(" {0} if ".format(target.name) +
1719 self._expr_val_str(cond_expr))
1721 selects_str = "\n".join(selects_str_rows)
1723 # Build reverse dependencies string
1724 if sc.rev_dep == "n":
1725 rev_dep_str = " (no reverse dependencies)"
1727 rev_dep_str = " " + self._expr_val_str(sc.rev_dep)
1729 res = _sep_lines("Symbol " + (sc.name if sc.name is not None else "(no name)"),
1730 "Type : " + typename[sc.type],
1731 "Value : " + value_str,
1732 "User value : " + user_value_str,
1733 "Visibility : " + visibility_str,
1734 "Is choice item : " + bool_str[sc.is_choice_symbol_],
1735 "Is defined : " + bool_str[sc.is_defined_],
1736 "Is from env. : " + bool_str[sc.is_from_env],
1737 "Is special : " + bool_str[sc.is_special_] + "\n")
1740 res += _sep_lines("Ranges:",
1743 res += _sep_lines("Prompts:",
1749 "Reverse dependencies:",
1751 "Additional dependencies from enclosing menus and if's:",
1752 additional_deps_str,
1753 "Locations: " + locations_str)
1758 # Choice-specific stuff
1761 # Build name string (for named choices)
1763 name_str = "(no name)"
1767 # Build selected symbol string
1768 sel = sc.get_selection()
1770 sel_str = "(no selection)"
1775 mode_str = s(sc.get_mode())
1777 # Build default values string
1778 if sc.def_exprs == []:
1779 defaults_str = " (no default values)"
1781 defaults_str_rows = []
1783 for (sym, cond_expr) in sc.orig_def_exprs:
1784 if cond_expr is None:
1785 defaults_str_rows.append(" {0}".format(sym.name))
1787 defaults_str_rows.append(" {0} if ".format(sym.name) +
1788 self._expr_val_str(cond_expr))
1790 defaults_str = "\n".join(defaults_str_rows)
1792 # Build contained symbols string
1793 names = [sym.name for sym in sc.get_symbols()]
1796 syms_string = "(empty)"
1798 syms_string = " ".join(names)
1800 return _sep_lines("Choice",
1801 "Name (for named choices): " + name_str,
1802 "Type : " + typename[sc.type],
1803 "Selected symbol : " + sel_str,
1804 "User value : " + user_value_str,
1805 "Mode : " + mode_str,
1806 "Visibility : " + visibility_str,
1807 "Optional : " + bool_str[sc.optional],
1814 "Additional dependencies from enclosing menus and if's:",
1815 additional_deps_str,
1816 "Locations: " + locations_str)
1818 def _expr_depends_on(self, expr, sym):
1819 """Reimplementation of expr_depends_symbol() from mconf.c. Used to
1820 determine if a submenu should be implicitly created, which influences what
1821 items inside choice statements are considered choice items."""
1826 if isinstance(expr, str):
1829 if isinstance(expr, Symbol):
1834 if e0 == EQUAL or e0 == UNEQUAL:
1835 return self._eq_to_sym(expr) is sym
1838 for and_expr in expr[1]:
1846 def _eq_to_sym(self, eq):
1847 """_expr_depends_on() helper. For (in)equalities of the form sym = y/m
1848 or sym != n, returns sym. For other (in)equalities, returns None."""
1849 relation, left, right = eq
1851 left = self._transform_n_m_y(left)
1852 right = self._transform_n_m_y(right)
1854 # Make sure the symbol (if any) appears to the left
1855 if not isinstance(left, Symbol):
1856 left, right = right, left
1858 if not isinstance(left, Symbol):
1861 if (relation == EQUAL and (right == "m" or right == "y")) or \
1862 (relation == UNEQUAL and right == "n"):
1867 def _transform_n_m_y(self, item):
1868 """_eq_to_sym() helper. Translates the symbols n, m, and y to their
1869 string equivalents."""
1878 def _warn(self, msg, filename = None, linenr = None):
1879 """For printing warnings to stderr."""
1880 if self.print_warnings:
1881 self._warn_or_undef_assign(msg, WARNING, filename, linenr)
1883 def _undef_assign(self, msg, filename = None, linenr = None):
1884 """For printing informational messages related to assignments
1885 to undefined variables to stderr."""
1886 if self.print_undef_assign:
1887 self._warn_or_undef_assign(msg, UNDEF_ASSIGN, filename, linenr)
1889 def _warn_or_undef_assign(self, msg, msg_type, filename, linenr):
1890 if filename is not None:
1891 sys.stderr.write("{0}:".format(_clean_up_path(filename)))
1892 if linenr is not None:
1893 sys.stderr.write("{0}:".format(linenr))
1895 if msg_type == WARNING:
1896 sys.stderr.write("warning: ")
1897 elif msg_type == UNDEF_ASSIGN:
1898 sys.stderr.write("info: ")
1900 _internal_error('Internal error while printing warning: unknown warning type "{0}".'
1903 sys.stderr.write(msg + "\n")
1905 def _get_expr_syms(expr):
1906 """Returns the set() of symbols appearing in expr."""
1912 if isinstance(expr, Symbol):
1916 if isinstance(expr, str):
1921 if e0 == OR or e0 == AND:
1922 for term in expr[1]:
1928 elif e0 == EQUAL or e0 == UNEQUAL:
1931 if isinstance(v1, Symbol):
1934 if isinstance(v2, Symbol):
1938 _internal_error("Internal error while fetching symbols from an "
1939 "expression with token stream {0}.".format(expr))
1946 # Construction of expressions
1949 # These functions as well as the _eval_min/max() functions above equate
1950 # None with "y", which is usually what we want, but needs to be kept in
1953 def _make_or(e1, e2):
1954 # Perform trivial simplification and avoid None's (which
1955 # correspond to y's)
1956 if e1 is None or e2 is None or \
1957 e1 == "y" or e2 == "y":
1966 # Prefer to merge/update argument list if possible instead of creating
1969 if isinstance(e1, tuple) and e1[0] == OR:
1970 if isinstance(e2, tuple) and e2[0] == OR:
1971 return (OR, e1[1] + e2[1])
1972 return (OR, e1[1] + [e2])
1974 if isinstance(e2, tuple) and e2[0] == OR:
1975 return (OR, e2[1] + [e1])
1977 return (OR, [e1, e2])
1979 # Note: returns None if e1 == e2 == None
1981 def _make_and(e1, e2):
1982 if e1 == "n" or e2 == "n":
1985 if e1 is None or e1 == "y":
1988 if e2 is None or e2 == "y":
1991 # Prefer to merge/update argument list if possible instead of creating
1994 if isinstance(e1, tuple) and e1[0] == AND:
1995 if isinstance(e2, tuple) and e2[0] == AND:
1996 return (AND, e1[1] + e2[1])
1997 return (AND, e1[1] + [e2])
1999 if isinstance(e2, tuple) and e2[0] == AND:
2000 return (AND, e2[1] + [e1])
2002 return (AND, [e1, e2])
2005 # Constants and functions related to types, parsing, evaluation and printing,
2006 # put globally to unclutter the Config class a bit.
2010 (T_OR, T_AND, T_NOT,
2011 T_OPEN_PAREN, T_CLOSE_PAREN,
2013 T_MAINMENU, T_MENU, T_ENDMENU,
2014 T_SOURCE, T_CHOICE, T_ENDCHOICE,
2015 T_COMMENT, T_CONFIG, T_MENUCONFIG,
2016 T_HELP, T_IF, T_ENDIF, T_DEPENDS, T_ON,
2017 T_OPTIONAL, T_PROMPT, T_DEFAULT,
2018 T_BOOL, T_TRISTATE, T_HEX, T_INT, T_STRING,
2019 T_DEF_BOOL, T_DEF_TRISTATE,
2020 T_SELECT, T_RANGE, T_OPTION, T_ENV,
2021 T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(0, 38)
2023 # Keyword to token map
2025 "mainmenu" : T_MAINMENU,
2027 "endmenu" : T_ENDMENU,
2029 "endchoice" : T_ENDCHOICE,
2030 "source" : T_SOURCE,
2031 "choice" : T_CHOICE,
2032 "config" : T_CONFIG,
2033 "comment" : T_COMMENT,
2034 "menuconfig" : T_MENUCONFIG,
2037 "depends" : T_DEPENDS,
2039 "optional" : T_OPTIONAL,
2040 "prompt" : T_PROMPT,
2041 "default" : T_DEFAULT,
2044 "tristate" : T_TRISTATE,
2047 "def_bool" : T_DEF_BOOL,
2048 "def_tristate" : T_DEF_TRISTATE,
2049 "string" : T_STRING,
2050 "select" : T_SELECT,
2052 "option" : T_OPTION,
2054 "defconfig_list" : T_DEFCONFIG_LIST,
2055 "modules" : T_MODULES,
2056 "visible" : T_VISIBLE }
2058 # Strings to use for True and False
2059 bool_str = { False : "false", True : "true" }
2061 # Tokens after which identifier-like lexemes are treated as strings. T_CHOICE
2062 # is included to avoid symbols being registered for named choices.
2063 string_lex = frozenset((T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING, T_CHOICE,
2064 T_PROMPT, T_MENU, T_COMMENT, T_SOURCE, T_MAINMENU))
2066 # Matches the initial token on a line; see _tokenize().
2067 initial_token_re = re.compile(r"[^\w]*(\w+)")
2069 # Matches an identifier/keyword optionally preceded by whitespace
2070 id_keyword_re = re.compile(r"\s*([\w./-]+)")
2072 # Regular expressions for parsing .config files
2073 set_re = re.compile(r"CONFIG_(\w+)=(.*)")
2074 unset_re = re.compile(r"# CONFIG_(\w+) is not set")
2076 # Regular expression for finding $-references to symbols in strings
2077 sym_ref_re = re.compile(r"\$[A-Za-z_][0-9A-Za-z_]*")
2079 # Integers representing symbol types
2080 UNKNOWN, BOOL, TRISTATE, STRING, HEX, INT = range(0, 6)
2082 # Strings to use for types
2084 UNKNOWN : "unknown",
2086 TRISTATE : "tristate",
2091 # Token to type mapping
2092 token_to_type = { T_BOOL : BOOL,
2093 T_TRISTATE : TRISTATE,
2098 # Default values for symbols of different types (the value the symbol gets if
2099 # it is not assigned a user value and none of its 'default' clauses kick in)
2100 default_value = { BOOL : "n",
2106 # Indicates that no item is selected in a choice statement
2109 # Integers representing expression types
2110 OR, AND, NOT, EQUAL, UNEQUAL = range(0, 5)
2112 # Map from tristate values to integers
2113 tri_to_int = { "n" : 0, "m" : 1, "y" : 2 }
2115 # Printing-related stuff
2117 op_to_str = { AND : " && ",
2122 precedence = { OR : 0, AND : 1, NOT : 2 }
2124 # Types of informational messages
2128 def _intersperse(lst, op):
2129 """_expr_to_str() helper. Gets the string representation of each expression in lst
2130 and produces a list where op has been inserted between the elements."""
2136 def handle_sub_expr(expr):
2137 no_parens = isinstance(expr, (str, Symbol)) or \
2138 expr[0] in (EQUAL, UNEQUAL) or \
2139 precedence[op] <= precedence[expr[0]]
2142 res.extend(_expr_to_str_rec(expr))
2146 op_str = op_to_str[op]
2148 handle_sub_expr(lst[0])
2149 for expr in lst[1:]:
2151 handle_sub_expr(expr)
2155 def _expr_to_str(expr):
2156 s = "".join(_expr_to_str_rec(expr))
2159 def _sym_str_string(sym_or_str):
2160 if isinstance(sym_or_str, str):
2161 return '"{0}"'.format(sym_or_str)
2162 return sym_or_str.name
2164 def _expr_to_str_rec(expr):
2168 if isinstance(expr, (Symbol, str)):
2169 return [_sym_str_string(expr)]
2173 if e0 == OR or e0 == AND:
2174 return _intersperse(expr[1], expr[0])
2177 need_parens = not isinstance(expr[1], (str, Symbol))
2182 res.extend(_expr_to_str_rec(expr[1]))
2187 if e0 == EQUAL or e0 == UNEQUAL:
2188 return [_sym_str_string(expr[1]),
2190 _sym_str_string(expr[2])]
2194 """Represents a list of items (symbols, menus, choice statements and
2195 comments) appearing at the top-level of a file or witin a menu, choice or
2201 def get_items(self):
2204 def add_item(self, item):
2205 self.items.append(item)
2207 def _make_conf(self):
2208 # Collect the substrings in a list and later use join() instead of +=
2209 # to build the final .config contents. With older Python versions, this
2210 # yields linear instead of quadratic complexity.
2212 for item in self.items:
2213 strings.extend(item._make_conf())
2217 def add_depend_expr(self, expr):
2218 for item in self.items:
2219 item.add_depend_expr(expr)
2223 """Base class for symbols and other Kconfig constructs. Subclasses are
2224 Symbol, Choice, Menu, and Comment."""
2226 def is_symbol(self):
2227 """Returns True if the item is a symbol, otherwise False. Short for
2228 isinstance(item, kconfiglib.Symbol)."""
2229 return isinstance(self, Symbol)
2231 def is_choice(self):
2232 """Returns True if the item is a choice, otherwise False. Short for
2233 isinstance(item, kconfiglib.Choice)."""
2234 return isinstance(self, Choice)
2237 """Returns True if the item is a menu, otherwise False. Short for
2238 isinstance(item, kconfiglib.Menu)."""
2239 return isinstance(self, Menu)
2241 def is_comment(self):
2242 """Returns True if the item is a comment, otherwise False. Short for
2243 isinstance(item, kconfiglib.Comment)."""
2244 return isinstance(self, Comment)
2246 class _HasVisibility():
2248 """Base class for elements that have a "visibility" that acts as an upper
2249 limit on the values a user can set for them. Subclasses are Symbol and
2250 Choice (which supply some of the attributes)."""
2253 self.cached_visibility = None
2256 def _invalidate(self):
2257 self.cached_visibility = None
2259 def _get_visibility(self):
2260 if self.cached_visibility is None:
2262 for (prompt, cond_expr) in self.prompts:
2263 vis = self.config._eval_max(vis, cond_expr)
2265 if isinstance(self, Symbol) and self.is_choice_symbol_:
2266 vis = self.config._eval_min(vis, self.parent._get_visibility())
2268 # Promote "m" to "y" if we're dealing with a non-tristate
2269 if vis == "m" and self.type != TRISTATE:
2272 self.cached_visibility = vis
2274 return self.cached_visibility
2276 class Symbol(Item, _HasVisibility):
2278 """Represents a configuration symbol - e.g. FOO for
2287 def get_value(self):
2288 """Calculate and return the value of the symbol. See also
2289 Symbol.set_user_value()."""
2291 if self.cached_value is not None:
2292 return self.cached_value
2294 self.write_to_conf = False
2296 # As a quirk of Kconfig, undefined symbols get their name as their
2297 # value. This is why things like "FOO = bar" work for seeing if FOO has
2299 if self.type == UNKNOWN:
2300 self.cached_value = self.name
2303 new_val = default_value[self.type]
2305 vis = self._get_visibility()
2307 if self.type == BOOL or self.type == TRISTATE:
2308 # The visibility and mode (modules-only or single-selection) of
2309 # choice items will be taken into account in self._get_visibility()
2311 if self.is_choice_symbol_:
2313 choice = self.parent
2314 mode = choice.get_mode()
2316 self.write_to_conf = (mode != "n")
2319 new_val = "y" if (choice.get_selection() is self) else "n"
2321 if self.user_val == "m" or self.user_val == "y":
2328 # If the symbol is visible and has a user value, use that.
2329 # Otherwise, look at defaults.
2330 self.write_to_conf = True
2332 if self.user_val is not None:
2333 new_val = self.config._eval_min(self.user_val, vis)
2334 use_defaults = False
2337 for (val_expr, cond_expr) in self.def_exprs:
2338 cond_eval = self.config._eval_expr(cond_expr)
2340 if cond_eval != "n":
2341 self.write_to_conf = True
2342 new_val = self.config._eval_min(val_expr, cond_eval)
2345 # Reverse dependencies take precedence
2346 rev_dep_val = self.config._eval_expr(self.rev_dep)
2348 if rev_dep_val != "n":
2349 self.write_to_conf = True
2350 new_val = self.config._eval_max(new_val, rev_dep_val)
2352 # Promote "m" to "y" for booleans
2353 if new_val == "m" and self.type == BOOL:
2356 elif self.type == STRING:
2360 self.write_to_conf = True
2361 if self.user_val is not None:
2362 new_val = self.user_val
2363 use_defaults = False
2366 for (val_expr, cond_expr) in self.def_exprs:
2367 if self.config._eval_expr(cond_expr) != "n":
2368 self.write_to_conf = True
2369 new_val = self.config._get_str_value(val_expr)
2372 elif self.type == HEX or self.type == INT:
2373 has_active_range = False
2378 base = 16 if self.type == HEX else 10
2380 for(l, h, cond_expr) in self.ranges:
2381 if self.config._eval_expr(cond_expr) != "n":
2382 has_active_range = True
2384 low_str = self.config._get_str_value(l)
2385 high_str = self.config._get_str_value(h)
2387 low = int(low_str, base) if \
2388 _is_base_n(low_str, base) else 0
2389 high = int(high_str, base) if \
2390 _is_base_n(high_str, base) else 0
2395 self.write_to_conf = True
2397 if self.user_val is not None and \
2398 _is_base_n(self.user_val, base) and \
2399 (not has_active_range or
2400 low <= int(self.user_val, base) <= high):
2402 # If the user value is OK, it is stored in exactly the same
2403 # form as specified in the assignment (with or without
2406 use_defaults = False
2407 new_val = self.user_val
2410 for (val_expr, cond_expr) in self.def_exprs:
2411 if self.config._eval_expr(cond_expr) != "n":
2412 self.write_to_conf = True
2414 # If the default value is OK, it is stored in exactly
2415 # the same form as specified. Otherwise, it is clamped
2416 # to the range, and the output has "0x" as appropriate
2419 new_val = self.config._get_str_value(val_expr)
2421 if _is_base_n(new_val, base):
2422 new_val_num = int(new_val, base)
2423 if has_active_range:
2426 if new_val_num < low:
2428 elif new_val_num > high:
2431 if clamped_val is not None:
2432 new_val = (hex(clamped_val) if \
2433 self.type == HEX else str(clamped_val))
2436 else: # For the for loop
2437 # If no user value or default kicks in but the hex/int has
2438 # an active range, then the low end of the range is used,
2439 # provided it's > 0, with "0x" prepended as appropriate.
2441 if has_active_range and low > 0:
2442 new_val = (hex(low) if self.type == HEX else str(low))
2444 self.cached_value = new_val
2447 def set_user_value(self, v):
2448 """Sets the user value of the symbol.
2450 Equal in effect to assigning the value to the symbol within a .config
2451 file. Use get_lower/upper_bound() or get_assignable_values() to find
2452 the range of currently assignable values for bool and tristate symbols;
2453 setting values outside this range will cause the user value to differ
2454 from the result of Symbol.get_value() (be truncated). Values that are
2455 invalid for the type (such as a_bool.set_user_value("foo")) are
2456 ignored, and a warning is emitted if an attempt is made to assign such
2459 For any type of symbol, is_modifiable() can be used to check if a user
2460 value will currently have any effect on the symbol, as determined by
2461 its visibility and range of assignable values. Any value that is valid
2462 for the type (bool, tristate, etc.) will end up being reflected in
2463 get_user_value() though, and might have an effect later if conditions
2464 change. To get rid of the user value, use unset_user_value().
2466 Any symbols dependent on the symbol are (recursively) invalidated, so
2467 things will just work with regards to dependencies.
2469 v -- The user value to give to the symbol."""
2470 self._set_user_value_no_invalidate(v, False)
2472 # There might be something more efficient you could do here, but play
2474 if self.name == "MODULES":
2475 self.config._invalidate_all()
2479 self._invalidate_dependent()
2481 def unset_user_value(self):
2482 """Resets the user value of the symbol, as if the symbol had never
2483 gotten a user value via Config.load_config() or
2484 Symbol.set_user_value()."""
2485 self._unset_user_value_no_recursive_invalidate()
2486 self._invalidate_dependent()
2488 def get_user_value(self):
2489 """Returns the value assigned to the symbol in a .config or via
2490 Symbol.set_user_value() (provided the value was valid for the type of the
2491 symbol). Returns None in case of no user value."""
2492 return self.user_val
2495 """Returns the name of the symbol."""
2498 def get_upper_bound(self):
2499 """For string/hex/int symbols and for bool and tristate symbols that
2500 cannot be modified (see is_modifiable()), returns None.
2502 Otherwise, returns the highest value the symbol can be set to with
2503 Symbol.set_user_value() (that will not be truncated): one of "m" or "y",
2504 arranged from lowest to highest. This corresponds to the highest value
2505 the symbol could be given in e.g. the 'make menuconfig' interface.
2507 See also the tri_less*() and tri_greater*() functions, which could come
2509 if self.type != BOOL and self.type != TRISTATE:
2511 rev_dep = self.config._eval_expr(self.rev_dep)
2512 # A bool selected to "m" gets promoted to "y"
2513 if self.type == BOOL and rev_dep == "m":
2515 vis = self._get_visibility()
2516 if (tri_to_int[vis] - tri_to_int[rev_dep]) > 0:
2520 def get_lower_bound(self):
2521 """For string/hex/int symbols and for bool and tristate symbols that
2522 cannot be modified (see is_modifiable()), returns None.
2524 Otherwise, returns the lowest value the symbol can be set to with
2525 Symbol.set_user_value() (that will not be truncated): one of "n" or "m",
2526 arranged from lowest to highest. This corresponds to the lowest value
2527 the symbol could be given in e.g. the 'make menuconfig' interface.
2529 See also the tri_less*() and tri_greater*() functions, which could come
2531 if self.type != BOOL and self.type != TRISTATE:
2533 rev_dep = self.config._eval_expr(self.rev_dep)
2534 # A bool selected to "m" gets promoted to "y"
2535 if self.type == BOOL and rev_dep == "m":
2537 if (tri_to_int[self._get_visibility()] - tri_to_int[rev_dep]) > 0:
2541 def get_assignable_values(self):
2542 """For string/hex/int symbols and for bool and tristate symbols that
2543 cannot be modified (see is_modifiable()), returns the empty list.
2545 Otherwise, returns a list containing the user values that can be
2546 assigned to the symbol (that won't be truncated). Usage example:
2548 if "m" in sym.get_assignable_values():
2549 sym.set_user_value("m")
2551 This is basically a more convenient interface to
2552 get_lower/upper_bound() when wanting to test if a particular tristate
2553 value can be assigned."""
2554 if self.type != BOOL and self.type != TRISTATE:
2556 rev_dep = self.config._eval_expr(self.rev_dep)
2557 # A bool selected to "m" gets promoted to "y"
2558 if self.type == BOOL and rev_dep == "m":
2560 res = ["n", "m", "y"][tri_to_int[rev_dep] :
2561 tri_to_int[self._get_visibility()] + 1]
2562 return res if len(res) > 1 else []
2565 """Returns the type of the symbol: one of UNKNOWN, BOOL, TRISTATE,
2566 STRING, HEX, or INT. These are defined at the top level of the module,
2567 so you'd do something like
2569 if sym.get_type() == kconfiglib.STRING:
2573 def get_visibility(self):
2574 """Returns the visibility of the symbol: one of "n", "m" or "y". For
2575 bool and tristate symbols, this is an upper bound on the value users
2576 can set for the symbol. For other types of symbols, a visibility of "n"
2577 means the user value will be ignored. A visibility of "n" corresponds
2578 to not being visible in the 'make *config' interfaces.
2580 Example (assuming we're running with modules enabled -- i.e., MODULES
2583 # Assume this has been assigned 'n'
2587 # Assume this has been assigned 'm'
2591 # Has visibility 'n'
2596 # Has visibility 'm'
2601 # Has visibility 'y'
2605 # Has no prompt, and hence visibility 'n'
2609 Having visibility be tri-valued ensures that e.g. a symbol cannot be
2610 set to "y" by the user if it depends on a symbol with value "m", which
2613 You should probably look at get_lower/upper_bound(),
2614 get_assignable_values() and is_modifiable() before using this."""
2615 return self._get_visibility()
2617 def get_parent(self):
2618 """Returns the menu or choice statement that contains the symbol, or
2619 None if the symbol is at the top level. Note that if statements are
2620 treated as syntactic and do not have an explicit class
2624 def get_referenced_symbols(self, refs_from_enclosing = False):
2625 """Returns the set() of all symbols referenced by this symbol. For
2626 example, the symbol defined by
2630 prompt "foo" if A && B
2635 references the symbols A through G.
2637 refs_from_enclosing (default: False) -- If True, the symbols
2638 referenced by enclosing menus and if's will be
2639 included in the result."""
2640 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
2642 def get_selected_symbols(self):
2643 """Returns the set() of all symbols X for which this symbol has a
2644 'select X' or 'select X if Y' (regardless of whether Y is satisfied or
2645 not). This is a subset of the symbols returned by
2646 get_referenced_symbols()."""
2647 return self.selected_syms
2650 """Returns the help text of the symbol, or None if the symbol has no
2654 def get_config(self):
2655 """Returns the Config instance this symbol is from."""
2658 def get_def_locations(self):
2659 """Returns a list of (filename, linenr) tuples, where filename (string)
2660 and linenr (int) represent a location where the symbol is defined. For
2661 the vast majority of symbols this list will only contain one element.
2662 For the following Kconfig, FOO would get two entries: the lines marked
2671 return self.def_locations
2673 def get_ref_locations(self):
2674 """Returns a list of (filename, linenr) tuples, where filename (string)
2675 and linenr (int) represent a location where the symbol is referenced in
2676 the configuration. For example, the lines marked by * would be included
2681 default BAR || FOO *
2693 config FOO (definition not included)
2696 return self.ref_locations
2698 def is_modifiable(self):
2699 """Returns True if the value of the symbol could be modified by calling
2700 Symbol.set_user_value() and False otherwise.
2702 For bools and tristates, this corresponds to the symbol being visible
2703 in the 'make menuconfig' interface and not already being pinned to a
2704 specific value (e.g. because it is selected by another symbol).
2706 For strings and numbers, this corresponds to just being visible. (See
2707 Symbol.get_visibility().)"""
2708 if self.is_special_:
2710 if self.type == BOOL or self.type == TRISTATE:
2711 rev_dep = self.config._eval_expr(self.rev_dep)
2712 # A bool selected to "m" gets promoted to "y"
2713 if self.type == BOOL and rev_dep == "m":
2715 return (tri_to_int[self._get_visibility()] -
2716 tri_to_int[rev_dep]) > 0
2717 return self._get_visibility() != "n"
2719 def is_defined(self):
2720 """Returns False if the symbol is referred to in the Kconfig but never
2721 actually defined, otherwise True."""
2722 return self.is_defined_
2724 def is_special(self):
2725 """Returns True if the symbol is one of the special symbols n, m, y, or
2726 UNAME_RELEASE, or gets its value from the environment. Otherwise,
2728 return self.is_special_
2730 def is_from_environment(self):
2731 """Returns True if the symbol gets its value from the environment.
2732 Otherwise, returns False."""
2733 return self.is_from_env
2735 def has_ranges(self):
2736 """Returns True if the symbol is of type INT or HEX and has ranges that
2737 limits what values it can take on, otherwise False."""
2738 return self.ranges != []
2740 def is_choice_symbol(self):
2741 """Returns True if the symbol is in a choice statement and is an actual
2742 choice symbol (see Choice.get_symbols()); otherwise, returns
2744 return self.is_choice_symbol_
2746 def is_choice_selection(self):
2747 """Returns True if the symbol is contained in a choice statement and is
2748 the selected item, otherwise False. Equivalent to 'sym.is_choice_symbol()
2749 and sym.get_parent().get_selection() is sym'."""
2750 return self.is_choice_symbol_ and self.parent.get_selection() is self
2753 """Returns a string containing various information about the symbol."""
2754 return self.config._get_sym_or_choice_str(self)
2761 """Symbol constructor -- not intended to be called directly by
2762 kconfiglib clients."""
2764 # Set default values
2765 _HasVisibility.__init__(self)
2777 # The prompt, default value and select conditions without any
2778 # dependencies from menus or if's propagated to them
2780 self.orig_prompts = []
2781 self.orig_def_exprs = []
2782 self.orig_selects = []
2784 # Dependencies inherited from containing menus and if's
2785 self.deps_from_containing = None
2789 # The set of symbols referenced by this symbol (see
2790 # get_referenced_symbols())
2791 self.referenced_syms = set()
2793 # The set of symbols selected by this symbol (see
2794 # get_selected_symbols())
2795 self.selected_syms = set()
2797 # Like 'referenced_syms', but includes symbols from
2798 # dependencies inherited from enclosing menus and if's
2799 self.all_referenced_syms = set()
2801 # This is set to True for "actual" choice symbols. See
2802 # Choice._determine_actual_symbols(). The trailing underscore avoids a
2803 # collision with is_choice_symbol().
2804 self.is_choice_symbol_ = False
2806 # This records only dependencies specified with 'depends on'. Needed
2807 # when determining actual choice items (hrrrr...). See also
2808 # Choice._determine_actual_symbols().
2809 self.menu_dep = None
2811 # See Symbol.get_ref/def_locations().
2812 self.def_locations = []
2813 self.ref_locations = []
2815 self.user_val = None
2819 # Should the symbol get an entry in .config?
2820 self.write_to_conf = False
2822 # Caches the calculated value
2823 self.cached_value = None
2825 # Note: An instance variable 'self.dep' gets set on the Symbol in
2826 # Config._build_dep(), linking the symbol to the symbols that
2827 # immediately depend on it (in a caching/invalidation sense). The total
2828 # set of dependent symbols for the symbol (the transitive closure) is
2829 # calculated on an as-needed basis in _get_dependent().
2831 # Caches the total list of dependent symbols. Calculated in
2833 self.cached_deps = None
2835 # Does the symbol have an entry in the Kconfig file? The trailing
2836 # underscore avoids a collision with is_defined().
2837 self.is_defined_ = False
2839 # Does the symbol get its value in some special way, e.g. from the
2840 # environment or by being one of the special symbols n, m, and y? If
2841 # so, the value is stored in self.cached_value, which is never
2842 # invalidated. The trailing underscore avoids a collision with
2844 self.is_special_ = False
2846 # Does the symbol get its value from the environment?
2847 self.is_from_env = False
2849 def _invalidate(self):
2850 if self.is_special_:
2853 if self.is_choice_symbol_:
2854 self.parent._invalidate()
2856 _HasVisibility._invalidate(self)
2858 self.write_to_conf = False
2859 self.cached_value = None
2861 def _invalidate_dependent(self):
2862 for sym in self._get_dependent():
2865 def _set_user_value_no_invalidate(self, v, suppress_load_warnings):
2866 """Like set_user_value(), but does not invalidate any symbols.
2868 suppress_load_warnings --
2869 some warnings are annoying when loading a .config that can be helpful
2870 when manually invoking set_user_value(). This flag is set to True to
2871 suppress such warnings.
2873 Perhaps this could be made optional for load_config() instead."""
2875 if self.is_special_:
2876 if self.is_from_env:
2877 self.config._warn('attempt to assign the value "{0}" to the '
2878 'symbol {1}, which gets its value from the '
2879 'environment. Assignment ignored.'
2880 .format(v, self.name))
2882 self.config._warn('attempt to assign the value "{0}" to the '
2883 'special symbol {1}. Assignment ignored.'
2884 .format(v, self.name))
2889 if not self.is_defined_:
2890 filename, linenr = self.ref_locations[0]
2892 self.config._undef_assign('attempt to assign the value "{0}" to {1}, '
2893 "which is referenced at {2}:{3} but never "
2894 "defined. Assignment ignored."
2895 .format(v, self.name, filename, linenr))
2898 # Check if the value is valid for our type
2900 if not (( self.type == BOOL and (v == "n" or v == "y") ) or
2901 ( self.type == TRISTATE and (v == "n" or v == "m" or
2903 ( self.type == STRING ) or
2904 ( self.type == INT and _is_base_n(v, 10) ) or
2905 ( self.type == HEX and _is_base_n(v, 16) )):
2907 self.config._warn('the value "{0}" is invalid for {1}, which has type {2}. '
2908 "Assignment ignored."
2909 .format(v, self.name, typename[self.type]))
2912 if self.prompts == [] and not suppress_load_warnings:
2913 self.config._warn('assigning "{0}" to the symbol {1} which '
2914 'lacks prompts and thus has visibility "n". '
2915 'The assignment will have no effect.'
2916 .format(v, self.name))
2920 if self.is_choice_symbol_ and (self.type == BOOL or
2921 self.type == TRISTATE):
2922 choice = self.parent
2924 choice.user_val = self
2925 choice.user_mode = "y"
2927 choice.user_val = None
2928 choice.user_mode = "m"
2930 def _unset_user_value_no_recursive_invalidate(self):
2932 self.user_val = None
2934 if self.is_choice_symbol_:
2935 self.parent._unset_user_value()
2937 def _make_conf(self):
2938 if self.already_written:
2941 self.already_written = True
2943 # Note: write_to_conf is determined in get_value()
2944 val = self.get_value()
2945 if not self.write_to_conf:
2948 if self.type == BOOL or self.type == TRISTATE:
2949 if val == "m" or val == "y":
2950 return ["CONFIG_{0}={1}".format(self.name, val)]
2951 return ["# CONFIG_{0} is not set".format(self.name)]
2953 elif self.type == STRING:
2955 return ['CONFIG_{0}="{1}"'
2957 val.replace("\\", "\\\\").replace('"', '\\"'))]
2959 elif self.type == INT or self.type == HEX:
2960 return ["CONFIG_{0}={1}".format(self.name, val)]
2963 _internal_error('Internal error while creating .config: unknown type "{0}".'
2966 def _get_dependent(self):
2967 """Returns the set of symbols that should be invalidated if the value
2968 of the symbol changes, because they might be affected by the change.
2969 Note that this is an internal API -- it's probably of limited
2970 usefulness to clients."""
2971 if self.cached_deps is not None:
2972 return self.cached_deps
2976 self._add_dependent_ignore_siblings(res)
2977 if self.is_choice_symbol_:
2978 for s in self.parent.get_symbols():
2981 s._add_dependent_ignore_siblings(res)
2983 self.cached_deps = res
2986 def _add_dependent_ignore_siblings(self, to):
2987 """Calculating dependencies gets a bit tricky for choice items as they
2988 all depend on each other, potentially leading to infinite recursion.
2989 This helper function calculates dependencies ignoring the other symbols
2990 in the choice. It also works fine for symbols that are not choice
2994 to |= s._get_dependent()
2996 def _has_auto_menu_dep_on(self, on):
2997 """See Choice._determine_actual_symbols()."""
2998 if not isinstance(self.parent, Choice):
2999 _internal_error("Attempt to determine auto menu dependency for symbol ouside of choice.")
3001 if self.prompts == []:
3002 # If we have no prompt, use the menu dependencies instead (what was
3003 # specified with 'depends on')
3004 return self.menu_dep is not None and \
3005 self.config._expr_depends_on(self.menu_dep, on)
3007 for (_, cond_expr) in self.prompts:
3008 if self.config._expr_depends_on(cond_expr, on):
3015 """Represents a menu statement."""
3021 def get_config(self):
3022 """Return the Config instance this menu is from."""
3025 def get_visibility(self):
3026 """Returns the visibility of the menu. This also affects the visibility
3027 of subitems. See also Symbol.get_visibility()."""
3028 return self.config._eval_expr(self.dep_expr)
3030 def get_visible_if_visibility(self):
3031 """Returns the visibility the menu gets from its 'visible if'
3032 condition. "y" if the menu has no 'visible if' condition."""
3033 return self.config._eval_expr(self.visible_if_expr)
3035 def get_items(self, recursive = False):
3036 """Returns a list containing the items (symbols, menus, choice
3037 statements and comments) in in the menu, in the same order that the
3038 items appear within the menu.
3040 recursive (default: False) -- True if items contained in items within
3041 the menu should be included
3042 recursively (preorder)."""
3045 return self.block.get_items()
3048 for item in self.block.get_items():
3050 if isinstance(item, Menu):
3051 res.extend(item.get_items(True))
3052 elif isinstance(item, Choice):
3053 res.extend(item.get_items())
3056 def get_symbols(self, recursive = False):
3057 """Returns a list containing the symbols in the menu, in the same order
3058 that they appear within the menu.
3060 recursive (default: False) -- True if symbols contained in items within
3061 the menu should be included
3064 return [item for item in self.get_items(recursive) if isinstance(item, Symbol)]
3066 def get_title(self):
3067 """Returns the title text of the menu."""
3070 def get_parent(self):
3071 """Returns the menu or choice statement that contains the menu, or
3072 None if the menu is at the top level. Note that if statements are
3073 treated as syntactic sugar and do not have an explicit class
3077 def get_referenced_symbols(self, refs_from_enclosing = False):
3078 """See Symbol.get_referenced_symbols()."""
3079 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3081 def get_location(self):
3082 """Returns the location of the menu as a (filename, linenr) tuple,
3083 where filename is a string and linenr an int."""
3084 return (self.filename, self.linenr)
3087 """Returns a string containing various information about the menu."""
3088 depends_on_str = self.config._expr_val_str(self.orig_deps,
3089 "(no dependencies)")
3090 visible_if_str = self.config._expr_val_str(self.visible_if_expr,
3091 "(no dependencies)")
3093 additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
3094 "(no additional dependencies)")
3096 return _sep_lines("Menu",
3097 "Title : " + self.title,
3098 "'depends on' dependencies : " + depends_on_str,
3099 "'visible if' dependencies : " + visible_if_str,
3100 "Additional dependencies from enclosing menus and if's:",
3101 additional_deps_str,
3102 "Location: {0}:{1}".format(self.filename, self.linenr))
3109 """Menu constructor -- not intended to be called directly by
3110 kconfiglib clients."""
3117 self.dep_expr = None
3119 # Dependency expression without dependencies from enclosing menus and
3121 self.orig_deps = None
3123 # Dependencies inherited from containing menus and if's
3124 self.deps_from_containing = None
3126 # The 'visible if' expression
3127 self.visible_if_expr = None
3129 # The set of symbols referenced by this menu (see
3130 # get_referenced_symbols())
3131 self.referenced_syms = set()
3133 # Like 'referenced_syms', but includes symbols from
3134 # dependencies inherited from enclosing menus and if's
3135 self.all_referenced_syms = None
3137 self.filename = None
3140 def _make_conf(self):
3141 item_conf = self.block._make_conf()
3143 if self.config._eval_expr(self.dep_expr) != "n" and \
3144 self.config._eval_expr(self.visible_if_expr) != "n":
3145 return ["\n#\n# {0}\n#".format(self.title)] + item_conf
3148 class Choice(Item, _HasVisibility):
3150 """Represents a choice statement. A choice can be in one of three modes:
3152 "n" - The choice is not visible and no symbols can be selected.
3154 "m" - Any number of symbols can be set to "m". The rest will be "n". This
3155 is safe since potentially conflicting options don't actually get
3156 compiled into the kernel simultaneously with "m".
3158 "y" - One symbol will be "y" while the rest are "n".
3160 Only tristate choices can be in "m" mode, and the visibility of the choice
3161 is an upper bound on the mode, so that e.g. a choice that depends on a
3162 symbol with value "m" will be in "m" mode.
3164 The mode changes automatically when a value is assigned to a symbol within
3167 See Symbol.get_visibility() too."""
3173 def get_selection(self):
3174 """Returns the symbol selected (either by the user or through
3175 defaults), or None if either no symbol is selected or the mode is not
3177 if self.cached_selection is not None:
3178 if self.cached_selection == NO_SELECTION:
3180 return self.cached_selection
3182 if self.get_mode() != "y":
3183 return self._cache_ret(None)
3185 # User choice available?
3186 if self.user_val is not None and \
3187 self.user_val._get_visibility() == "y":
3188 return self._cache_ret(self.user_val)
3191 return self._cache_ret(None)
3193 return self._cache_ret(self.get_selection_from_defaults())
3195 def get_selection_from_defaults(self):
3196 """Like Choice.get_selection(), but acts as if no symbol has been
3197 selected by the user and no 'optional' flag is in effect."""
3199 if self.actual_symbols == []:
3202 for (symbol, cond_expr) in self.def_exprs:
3203 if self.config._eval_expr(cond_expr) != "n":
3204 chosen_symbol = symbol
3207 chosen_symbol = self.actual_symbols[0]
3209 # Is the chosen symbol visible?
3210 if chosen_symbol._get_visibility() != "n":
3211 return chosen_symbol
3212 # Otherwise, pick the first visible symbol
3213 for sym in self.actual_symbols:
3214 if sym._get_visibility() != "n":
3218 def get_user_selection(self):
3219 """If the choice is in "y" mode and has a user-selected symbol, returns
3220 that symbol. Otherwise, returns None."""
3221 return self.user_val
3223 def get_config(self):
3224 """Returns the Config instance this choice is from."""
3228 """For named choices, returns the name. Returns None for unnamed
3229 choices. No named choices appear anywhere in the kernel Kconfig files
3230 as of Linux 3.7.0-rc8."""
3234 """Returns the help text of the choice, or None if the choice has no
3239 """Returns the type of the choice. See Symbol.get_type()."""
3242 def get_items(self):
3243 """Gets all items contained in the choice in the same order as within
3244 the configuration ("items" instead of "symbols" since choices and
3245 comments might appear within choices. This only happens in one place as
3246 of Linux 3.7.0-rc8, in drivers/usb/gadget/Kconfig)."""
3247 return self.block.get_items()
3249 def get_symbols(self):
3250 """Returns a list containing the choice's symbols.
3252 A quirk (perhaps a bug) of Kconfig is that you can put items within a
3253 choice that will not be considered members of the choice insofar as
3254 selection is concerned. This happens for example if one symbol within a
3255 choice 'depends on' the symbol preceding it, or if you put non-symbol
3256 items within choices.
3258 As of Linux 3.7.0-rc8, this seems to be used intentionally in one
3259 place: drivers/usb/gadget/Kconfig.
3261 This function returns the "proper" symbols of the choice in the order
3262 they appear in the choice, excluding such items. If you want all items
3263 in the choice, use get_items()."""
3264 return self.actual_symbols
3266 def get_parent(self):
3267 """Returns the menu or choice statement that contains the choice, or
3268 None if the choice is at the top level. Note that if statements are
3269 treated as syntactic sugar and do not have an explicit class
3273 def get_referenced_symbols(self, refs_from_enclosing = False):
3274 """See Symbol.get_referenced_symbols()."""
3275 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3277 def get_def_locations(self):
3278 """Returns a list of (filename, linenr) tuples, where filename (string)
3279 and linenr (int) represent a location where the choice is defined. For
3280 the vast majority of choices (all of them as of Linux 3.7.0-rc8) this
3281 list will only contain one element, but its possible for named choices
3282 to be defined in multiple locations."""
3283 return self.def_locations
3285 def get_visibility(self):
3286 """Returns the visibility of the choice statement: one of "n", "m" or
3287 "y". This acts as an upper limit on the mode of the choice (though bool
3288 choices can only have the mode "y"). See the class documentation for an
3289 explanation of modes."""
3290 return self._get_visibility()
3293 """Returns the mode of the choice. See the class documentation for
3294 an explanation of modes."""
3295 minimum_mode = "n" if self.optional else "m"
3296 mode = self.user_mode if self.user_mode is not None else minimum_mode
3297 mode = self.config._eval_min(mode, self._get_visibility())
3299 # Promote "m" to "y" for boolean choices
3300 if mode == "m" and self.type == BOOL:
3305 def is_optional(self):
3306 """Returns True if the symbol has the optional flag set (and so will default
3307 to "n" mode). Otherwise, returns False."""
3308 return self.optional
3311 """Returns a string containing various information about the choice
3313 return self.config._get_sym_or_choice_str(self)
3320 """Choice constructor -- not intended to be called directly by
3321 kconfiglib clients."""
3323 _HasVisibility.__init__(self)
3328 self.name = None # Yes, choices can be named
3332 self.optional = False
3335 # The prompts and default values without any dependencies from
3336 # enclosing menus or if's propagated
3338 self.orig_prompts = []
3339 self.orig_def_exprs = []
3341 # Dependencies inherited from containing menus and if's
3342 self.deps_from_containing = None
3344 # We need to filter out symbols that appear within the choice block but
3345 # are not considered choice items (see
3346 # Choice._determine_actual_symbols()) This list holds the "actual" choice
3348 self.actual_symbols = []
3350 # The set of symbols referenced by this choice (see
3351 # get_referenced_symbols())
3352 self.referenced_syms = set()
3354 # Like 'referenced_syms', but includes symbols from
3355 # dependencies inherited from enclosing menus and if's
3356 self.all_referenced_syms = set()
3358 # See Choice.get_def_locations()
3359 self.def_locations = []
3361 self.user_val = None
3362 self.user_mode = None
3364 self.cached_selection = None
3366 def _determine_actual_symbols(self):
3367 """If a symbol's visibility depends on the preceding symbol within a
3368 choice, it is no longer viewed as a choice item (quite possibly a bug,
3369 but some things consciously use it.. ugh. It stems from automatic
3370 submenu creation). In addition, it's possible to have choices and
3371 comments within choices, and those shouldn't be considered as choice
3372 items either. Only drivers/usb/gadget/Kconfig seems to depend on any of
3373 this. This method computes the "actual" items in the choice and sets
3374 the is_choice_symbol_ flag on them (retrieved via is_choice_symbol()).
3376 Don't let this scare you: an earlier version simply checked for a
3377 sequence of symbols where all symbols after the first appeared in the
3378 'depends on' expression of the first, and that worked fine. The added
3379 complexity is to be future-proof in the event that
3380 drivers/usb/gadget/Kconfig turns even more sinister. It might very well
3381 be overkilling things (especially if that file is refactored ;)."""
3383 items = self.block.get_items()
3385 # Items might depend on each other in a tree structure, so we need a
3386 # stack to keep track of the current tentative parent
3390 if not isinstance(item, Symbol):
3395 if item._has_auto_menu_dep_on(stack[-1]):
3396 # The item should not be viewed as a choice item, so don't
3397 # set item.is_choice_symbol_.
3403 item.is_choice_symbol_ = True
3404 self.actual_symbols.append(item)
3407 def _cache_ret(self, selection):
3408 # As None is used to indicate the lack of a cached value we can't use
3409 # that to cache the fact that the choice has no selection. Instead, we
3410 # use the symbolic constant NO_SELECTION.
3411 if selection is None:
3412 self.cached_selection = NO_SELECTION
3414 self.cached_selection = selection
3418 def _invalidate(self):
3419 _HasVisibility._invalidate(self)
3420 self.cached_selection = None
3422 def _unset_user_value(self):
3424 self.user_val = None
3425 self.user_mode = None
3427 def _make_conf(self):
3428 return self.block._make_conf()
3430 class Comment(Item):
3432 """Represents a comment statement."""
3438 def get_config(self):
3439 """Returns the Config instance this comment is from."""
3442 def get_visibility(self):
3443 """Returns the visibility of the comment. See also
3444 Symbol.get_visibility()."""
3445 return self.config._eval_expr(self.dep_expr)
3448 """Returns the text of the comment."""
3451 def get_parent(self):
3452 """Returns the menu or choice statement that contains the comment, or
3453 None if the comment is at the top level. Note that if statements are
3454 treated as syntactic sugar and do not have an explicit class
3458 def get_referenced_symbols(self, refs_from_enclosing = False):
3459 """See Symbol.get_referenced_symbols()."""
3460 return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms
3462 def get_location(self):
3463 """Returns the location of the comment as a (filename, linenr) tuple,
3464 where filename is a string and linenr an int."""
3465 return (self.filename, self.linenr)
3468 """Returns a string containing various information about the comment."""
3469 dep_str = self.config._expr_val_str(self.orig_deps, "(no dependencies)")
3471 additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
3472 "(no additional dependencies)")
3474 return _sep_lines("Comment",
3475 "Text: " + str(self.text),
3476 "Dependencies: " + dep_str,
3477 "Additional dependencies from enclosing menus and if's:",
3478 additional_deps_str,
3479 "Location: {0}:{1}".format(self.filename, self.linenr))
3486 """Comment constructor -- not intended to be called directly by
3487 kconfiglib clients."""
3493 self.dep_expr = None
3495 # Dependency expression without dependencies from enclosing menus and
3497 self.orig_deps = None
3499 # Dependencies inherited from containing menus and if's
3500 self.deps_from_containing = None
3502 # The set of symbols referenced by this comment (see
3503 # get_referenced_symbols())
3504 self.referenced_syms = set()
3506 # Like 'referenced_syms', but includes symbols from
3507 # dependencies inherited from enclosing menus and if's
3508 self.all_referenced_syms = None
3510 self.filename = None
3513 def _make_conf(self):
3514 if self.config._eval_expr(self.dep_expr) != "n":
3515 return ["\n#\n# {0}\n#".format(self.text)]
3520 """Class for working with sequences in a stream-like fashion; handy for tokens."""
3522 def __init__(self, items):
3524 self.length = len(self.items)
3528 if self.i >= self.length:
3531 item = self.items[self.i]
3535 def peek_next(self):
3536 return None if self.i >= self.length else self.items[self.i]
3538 def go_to_start(self):
3541 def __getitem__(self, index):
3542 return self.items[index]
3545 return len(self.items)
3548 return self.items == []
3550 def check(self, token):
3551 """Check if the next token is 'token'. If so, remove it from the token
3552 feed and return True. Otherwise, leave it in and return False."""
3553 if self.i >= self.length:
3556 if self.items[self.i] == token:
3562 def remove_while(self, pred):
3563 while self.i < self.length and pred(self.items[self.i]):
3568 _internal_error("Attempt to move back in Feed while already at the beginning.")
3571 class _FileFeed(_Feed):
3573 """Feed subclass that keeps track of the current filename and line
3576 def __init__(self, lines, filename):
3577 self.filename = _clean_up_path(filename)
3578 _Feed.__init__(self, lines)
3580 def get_filename(self):
3581 return self.filename
3583 def get_linenr(self):
3587 # Misc. public global utility functions
3590 def tri_less(v1, v2):
3591 """Returns True if the tristate v1 is less than the tristate v2, where "n",
3592 "m" and "y" are ordered from lowest to highest. Otherwise, returns
3594 return tri_to_int[v1] < tri_to_int[v2]
3596 def tri_less_eq(v1, v2):
3597 """Returns True if the tristate v1 is less than or equal to the tristate
3598 v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
3600 return tri_to_int[v1] <= tri_to_int[v2]
3602 def tri_greater(v1, v2):
3603 """Returns True if the tristate v1 is greater than the tristate v2, where
3604 "n", "m" and "y" are ordered from lowest to highest. Otherwise, returns
3606 return tri_to_int[v1] > tri_to_int[v2]
3608 def tri_greater_eq(v1, v2):
3609 """Returns True if the tristate v1 is greater than or equal to the tristate
3610 v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
3612 return tri_to_int[v1] >= tri_to_int[v2]
3615 # Helper functions, mostly related to text processing
3618 def _strip_quotes(s, line, filename, linenr):
3619 """Removes any quotes surrounding 's' if it has them; otherwise returns 's'
3624 if s[0] == '"' or s[0] == "'":
3625 if len(s) < 2 or s[-1] != s[0]:
3627 "malformed string literal",
3633 def _indentation(line):
3634 """Returns the indentation of the line, treating tab stops as being spaced
3635 8 characters apart."""
3637 _internal_error("Attempt to take indentation of blank line.")
3643 # Go to the next tab stop
3644 indent = (indent + 8) & ~7
3648 def _deindent(line, indent):
3649 """Deindent 'line' by 'indent' spaces."""
3650 line = line.expandtabs()
3651 if len(line) <= indent:
3653 return line[indent:]
3655 def _is_base_n(s, n):
3662 def _sep_lines(*args):
3663 """Returns a string comprised of all arguments, with newlines inserted
3665 return "\n".join(args)
3668 """Returns a new string with "#" inserted before each line in 's'."""
3671 res = "".join(["#" + line for line in s.splitlines(True)])
3672 if s.endswith("\n"):
3676 def _get_lines(filename):
3677 """Returns a list of lines from 'filename', joining any line ending in \\
3678 with the following line."""
3679 with open(filename, "r") as f:
3688 if line.endswith("\\\n"):
3695 def _strip_trailing_slash(path):
3696 """Removes any trailing slash from 'path'."""
3697 return path[:-1] if path.endswith("/") else path
3699 def _clean_up_path(path):
3700 """Strips any initial "./" and trailing slash from 'path'."""
3701 if path.startswith("./"):
3703 return _strip_trailing_slash(path)
3709 class Kconfig_Syntax_Error(Exception):
3710 """Exception raised for syntax errors."""
3713 class Internal_Error(Exception):
3714 """Exception raised for internal errors."""
3717 def _tokenization_error(s, index, filename, linenr):
3718 if filename is not None:
3719 assert linenr is not None
3720 sys.stderr.write("{0}:{1}:\n".format(filename, linenr))
3722 if s.endswith("\n"):
3725 # Calculate the visual offset corresponding to index 'index' in 's'
3726 # assuming tabstops are spaced 8 characters apart
3730 vis_index = (vis_index + 8) & ~7
3734 # Don't output actual tabs to be independent of how the terminal renders
3738 raise Kconfig_Syntax_Error, (
3739 _sep_lines("Error during tokenization at location indicated by caret.\n",
3741 " " * vis_index + "^\n"))
3743 def _parse_error(s, msg, filename, linenr):
3746 if filename is not None:
3747 assert linenr is not None
3748 error_str += "{0}:{1}: ".format(filename, linenr)
3750 if s.endswith("\n"):
3753 error_str += 'Error while parsing "{0}"'.format(s) + \
3754 ("." if msg is None else ": " + msg)
3756 raise Kconfig_Syntax_Error, error_str
3758 def _internal_error(msg):
3759 msg += "\nSorry! You may want to send an email to kconfiglib@gmail.com " \
3760 "to tell me about this. Include the message above and the stack " \
3761 "trace and describe what you were doing."
3763 raise Internal_Error, msg
3768 Config._tokenize = psyco.proxy(Config._tokenize)
3769 Config._eval_expr = psyco.proxy(Config._eval_expr)
3771 _indentation = psyco.proxy(_indentation)
3772 _get_lines = psyco.proxy(_get_lines)