#
# SPDX-License-Identifier:	ISC
#
# Author: Ulf Magnusson
#   https://github.com/ulfalizer/Kconfiglib

# This is Kconfiglib, a Python library for scripting, debugging, and extracting
# information from Kconfig-based configuration systems. To view the
# documentation, run
#
#  $ pydoc kconfiglib
#
# or, if you prefer HTML,
#
#  $ pydoc -w kconfiglib
#
# The examples/ subdirectory contains examples, to be run with e.g.
#
#  $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
#
# Look in testsuite.py for the test suite.

"""
Kconfiglib is a Python library for scripting and extracting information from
Kconfig-based configuration systems. Features include the following:

 - Symbol values and properties can be looked up and values assigned
   programmatically.
 - .config files can be read and written.
 - Expressions can be evaluated in the context of a Kconfig configuration.
 - Relations between symbols can be quickly determined, such as finding all
   symbols that reference a particular symbol.
 - Highly compatible with the scripts/kconfig/*conf utilities. The test suite
   automatically compares outputs between Kconfiglib and the C implementation
   for a large number of cases.

For the Linux kernel, scripts are run using

 $ make scriptconfig SCRIPT=<path to script> [SCRIPT_ARG=<arg>]

Running scripts via the 'scriptconfig' target ensures that required environment
variables (SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly.
Alternative architectures can be specified like for other 'make *config'
targets:

 $ make scriptconfig ARCH=mips SCRIPT=<path to script> [SCRIPT_ARG=<arg>]

The script will receive the name of the Kconfig file to load in sys.argv[1].
(As of Linux 3.7.0-rc8 this is always "Kconfig" from the kernel top-level
directory.) If an argument is provided with SCRIPT_ARG, it will appear in
sys.argv[2].

To get an interactive Python prompt with Kconfiglib preloaded and a Config
object 'c' created, use

 $ make iscriptconfig [ARCH=<architecture>]

Kconfiglib requires Python 2. For (i)scriptconfig the command to run the Python
interpreter can be passed in the environment variable PYTHONCMD (defaults to
'python'; PyPy works too and is a bit faster).

Look in the examples/ subdirectory for examples, which can be run with e.g.

 $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py

or

 $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG="kernel"

Look in testsuite.py for the test suite.

Credits: Written by Ulf "Ulfalizer" Magnusson

Send bug reports, suggestions and other feedback to kconfiglib@gmail.com .
Don't wrestle with internal APIs. Tell me what you need and I might add it in a
safe way as a client API instead."""

# If you have Psyco installed (32-bit installations, Python <= 2.6 only),
# setting this to True (right here, not at runtime) might give a nice speedup.
# (22% faster for parsing arch/x86/Kconfig and 58% faster for evaluating all
# symbols in it without a .config on my Core Duo.)
use_psyco = False

import os
import re
import string
import sys

class Config():

    """Represents a Kconfig configuration, e.g. for i386 or ARM. This is the
    set of symbols and other items appearing in the configuration together with
    their values. Creating any number of Config objects -- including for
    different architectures -- is safe; Kconfiglib has no global state."""

    #
    # Public interface
    #

    def __init__(self,
                 filename = "Kconfig",
                 base_dir = "$srctree",
                 print_warnings = True,
                 print_undef_assign = False):
        """Creates a new Config object, representing a Kconfig configuration.
        Raises Kconfig_Syntax_Error on syntax errors.

        filename (default: "Kconfig") -- The base Kconfig file of the
                 configuration. For the Linux kernel, this should usually be be
                 "Kconfig" from the top-level directory, as environment
                 variables will make sure the right Kconfig is included from
                 there (usually arch/<architecture>/Kconfig). If you are using
                 kconfiglib via 'make scriptconfig' the filename of the
                 correct Kconfig will be in sys.argv[1].

        base_dir (default: "$srctree") -- The base directory relative to which
                'source' statements within Kconfig files will work. For the
                Linux kernel this should be the top-level directory of the
                kernel tree. $-references to environment variables will be
                expanded.

                The environment variable 'srctree' is set by the Linux makefiles
                to the top-level kernel directory. A default of "." would not
                work if an alternative build directory is used.

        print_warnings (default: True) -- Set to True if warnings related to
                       this configuration should be printed to stderr. This can
                       be changed later with Config.set_print_warnings(). It is
                       provided as a constructor argument since warnings might
                       be generated during parsing.

        print_undef_assign (default: False) -- Set to True if informational
                           messages related to assignments to undefined symbols
                           should be printed to stderr for this configuration.
                           Can be changed later with
                           Config.set_print_undef_assign()."""

        # The set of all symbols, indexed by name (a string)
        self.syms = {}

        # The set of all defined symbols in the configuration in the order they
        # appear in the Kconfig files. This excludes the special symbols n, m,
        # and y as well as symbols that are referenced but never defined.
        self.kconfig_syms = []

        # The set of all named choices (yes, choices can have names), indexed
        # by name (a string)
        self.named_choices = {}

        def register_special_symbol(type, name, value):
            sym = Symbol()
            sym.is_special_ = True
            sym.is_defined_ = True
            sym.config = self
            sym.name = name
            sym.type = type
            sym.cached_value = value
            self.syms[name] = sym
            return sym

        # The special symbols n, m and y, used as shorthand for "n", "m" and
        # "y"
        self.n = register_special_symbol(TRISTATE, "n", "n")
        self.m = register_special_symbol(TRISTATE, "m", "m")
        self.y = register_special_symbol(TRISTATE, "y", "y")

        # DEFCONFIG_LIST uses this
        register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])

        # The symbol with "option defconfig_list" set, containing a list of
        # default .config files
        self.defconfig_sym = None

        # See Symbol.get_(src)arch()
        self.arch    = os.environ.get("ARCH")
        self.srcarch = os.environ.get("SRCARCH")

        # See Config.__init__(). We need this for get_defconfig_filename().
        self.srctree = os.environ.get("srctree")
        if self.srctree is None:
            self.srctree = "."

        self.filename = filename
        self.base_dir = _strip_trailing_slash(os.path.expandvars(base_dir))

        # The 'mainmenu' text
        self.mainmenu_text = None

        # The filename of the most recently loaded .config file
        self.config_filename = None

        # The textual header of the most recently loaded .config, uncommented
        self.config_header = None

        self.print_warnings = print_warnings
        self.print_undef_assign = print_undef_assign

        # Lists containing all choices, menus and comments in the configuration

        self.choices = []
        self.menus = []
        self.comments = []

        # For parsing routines that stop when finding a line belonging to a
        # different construct, these holds that line and the tokenized version
        # of that line. The purpose is to avoid having to re-tokenize the line,
        # which is inefficient and causes problems when recording references to
        # symbols.
        self.end_line = None
        self.end_line_tokens = None

        # See the comment in _parse_expr().
        self.parse_expr_cur_sym_or_choice = None
        self.parse_expr_line = None
        self.parse_expr_filename = None
        self.parse_expr_linenr = None
        self.parse_expr_transform_m = None

        # Parse the Kconfig files
        self.top_block = self._parse_file(filename, None, None, None)

        # Build Symbol.dep for all symbols
        self._build_dep()

    def load_config(self, filename, replace = True):
        """Loads symbol values from a file in the familiar .config format.
           Equivalent to calling Symbol.set_user_value() to set each of the
           values.

           filename -- The .config file to load. $-references to environment
                       variables will be expanded. For scripts to work even
                       when an alternative build directory is used with the
                       Linux kernel, you need to refer to the top-level kernel
                       directory with "$srctree".

           replace (default: True) -- True if the configuration should replace
                   the old configuration; False if it should add to it."""

        def warn_override(filename, linenr, name, old_user_val, new_user_val):
            self._warn("overriding the value of {0}. "
                       'Old value: "{1}", new value: "{2}".'
                        .format(name, old_user_val, new_user_val),
                       filename,
                       linenr)

        filename = os.path.expandvars(filename)

        # Put this first so that a missing file doesn't screw up our state
        line_feeder = _FileFeed(_get_lines(filename), filename)

        self.config_filename = filename

        # Invalidate everything. This is usually faster than finding the
        # minimal set of symbols that needs to be invalidated, as nearly all
        # symbols will tend to be affected anyway.
        if replace:
            self.unset_user_values()
        else:
            self._invalidate_all()

        # Read header

        self.config_header = None

        def is_header_line(line):
            return line.startswith("#") and \
                   not unset_re.match(line)

        first_line = line_feeder.get_next()

        if first_line is None:
            return

        if not is_header_line(first_line):
            line_feeder.go_back()
        else:
            self.config_header = first_line[1:]

            # Read remaining header lines
            while 1:
                line = line_feeder.get_next()

                if line is None:
                    break

                if not is_header_line(line):
                    line_feeder.go_back()
                    break

                self.config_header += line[1:]

            # Remove trailing newline
            if self.config_header.endswith("\n"):
                self.config_header = self.config_header[:-1]

        # Read assignments

        filename = line_feeder.get_filename()

        while 1:
            line = line_feeder.get_next()
            if line is None:
                return

            linenr = line_feeder.get_linenr()

            line = line.strip()

            set_re_match = set_re.match(line)
            if set_re_match:
                name, val = set_re_match.groups()
                # The unescaping producedure below should be safe since " can
                # only appear as \" inside the string
                val = _strip_quotes(val, line, filename, linenr)\
                      .replace('\\"', '"').replace("\\\\", "\\")
                if name in self.syms:
                    sym = self.syms[name]

                    old_user_val = sym.user_val
                    if old_user_val is not None:
                        warn_override(filename, linenr, name, old_user_val, val)

                    if sym.is_choice_symbol_:
                        user_mode = sym.parent.user_mode
                        if user_mode is not None and user_mode != val:
                            self._warn("assignment to {0} changes mode of containing "
                                       'choice from "{1}" to "{2}".'
                                       .format(name, val, user_mode),
                                       filename,
                                       linenr)

                    sym._set_user_value_no_invalidate(val, True)

                else:
                    self._undef_assign('attempt to assign the value "{0}" to the '
                                       "undefined symbol {1}."
                                       .format(val, name),
                                       filename,
                                       linenr)

            else:
                unset_re_match = unset_re.match(line)
                if unset_re_match:
                    name = unset_re_match.group(1)
                    if name in self.syms:
                        sym = self.syms[name]

                        old_user_val = sym.user_val
                        if old_user_val is not None:
                            warn_override(filename, linenr, name, old_user_val, "n")

                        sym._set_user_value_no_invalidate("n", True)

    def write_config(self, filename, header = None):
        """Writes out symbol values in the familiar .config format.

           filename -- The filename under which to save the configuration.

           header (default: None) -- A textual header that will appear at the
                  beginning of the file, with each line commented out
                  automatically. None means no header."""

        # already_written is set when _make_conf() is called on a symbol, so
        # that symbols defined in multiple locations only get one entry in the
        # .config. We need to reset it prior to writing out a new .config.
        for sym in self.syms.itervalues():
            sym.already_written = False

        with open(filename, "w") as f:
            # Write header
            if header is not None:
                f.write(_comment(header))
                f.write("\n")

            # Write configuration.
            # (You'd think passing a list around to all the nodes and appending
            # to it to avoid copying would be faster, but it's actually a lot
            # slower with PyPy, and about as fast with Python. Passing the file
            # around is slower too.)
            f.write("\n".join(self.top_block._make_conf()))
            f.write("\n")

    def get_kconfig_filename(self):
        """Returns the name of the (base) kconfig file this configuration was
        loaded from."""
        return self.filename

    def get_arch(self):
        """Returns the value the environment variable ARCH had at the time the
        Config instance was created, or None if ARCH was not set. For the
        kernel, this corresponds to the architecture being built for, with
        values such as "i386" or "mips"."""
        return self.arch

    def get_srcarch(self):
        """Returns the value the environment variable SRCARCH had at the time
        the Config instance was created, or None if SRCARCH was not set. For
        the kernel, this corresponds to the arch/ subdirectory containing
        architecture-specific source code."""
        return self.srcarch

    def get_srctree(self):
        """Returns the value the environment variable srctree had at the time
        the Config instance was created, or None if srctree was not defined.
        This variable points to the source directory and is used when building
        in a separate directory."""
        return self.srctree

    def get_config_filename(self):
        """Returns the name of the most recently loaded configuration file, or
        None if no configuration has been loaded."""
        return self.config_filename

    def get_mainmenu_text(self):
        """Returns the text of the 'mainmenu' statement (with $-references to
        symbols replaced by symbol values), or None if the configuration has no
        'mainmenu' statement."""
        return None if self.mainmenu_text is None else \
          self._expand_sym_refs(self.mainmenu_text)

    def get_defconfig_filename(self):
        """Returns the name of the defconfig file, which is the first existing
        file in the list given in a symbol having 'option defconfig_list' set.
        $-references to symbols will be expanded ("$FOO bar" -> "foo bar" if
        FOO has the value "foo"). Returns None in case of no defconfig file.
        Setting 'option defconfig_list' on multiple symbols currently results
        in undefined behavior.

        If the environment variable 'srctree' was set when the Config was
        created, get_defconfig_filename() will first look relative to that
        directory before looking in the current directory; see
        Config.__init__()."""

        if self.defconfig_sym is None:
            return None

        for (filename, cond_expr) in self.defconfig_sym.def_exprs:
            if self._eval_expr(cond_expr) == "y":
                filename = self._expand_sym_refs(filename)

                # We first look in $srctree. os.path.join() won't work here as
                # an absolute path in filename would override $srctree.
                srctree_filename = os.path.normpath(self.srctree + "/" + filename)
                if os.path.exists(srctree_filename):
                    return srctree_filename

                if os.path.exists(filename):
                    return filename

        return None

    def get_symbol(self, name):
        """Returns the symbol with name 'name', or None if no such symbol
        appears in the configuration. An alternative shorthand is conf[name],
        where conf is a Config instance, though that will instead raise
        KeyError if the symbol does not exist."""
        return self.syms.get(name)

    def get_top_level_items(self):
        """Returns a list containing the items (symbols, menus, choice
        statements and comments) at the top level of the configuration -- that
        is, all items that do not appear within a menu or choice. The items
        appear in the same order as within the configuration."""
        return self.top_block.get_items()

    def get_symbols(self, all_symbols = True):
        """Returns a list of symbols from the configuration. An alternative for
        iterating over all defined symbols (in the order of definition) is

        for sym in config:
            ...

        which relies on Config implementing __iter__() and is equivalent to

        for sym in config.get_symbols(False):
            ...

        all_symbols (default: True) -- If True, all symbols - including special
                    and undefined symbols - will be included in the result, in
                    an undefined order. If False, only symbols actually defined
                    and not merely referred to in the configuration will be
                    included in the result, and will appear in the order that
                    they are defined within the Kconfig configuration files."""
        return self.syms.values() if all_symbols else self.kconfig_syms

    def get_choices(self):
        """Returns a list containing all choice statements in the
        configuration, in the order they appear in the Kconfig files."""
        return self.choices

    def get_menus(self):
        """Returns a list containing all menus in the configuration, in the
        order they appear in the Kconfig files."""
        return self.menus

    def get_comments(self):
        """Returns a list containing all comments in the configuration, in the
        order they appear in the Kconfig files."""
        return self.comments

    def eval(self, s):
        """Returns the value of the expression 's' -- where 's' is represented
        as a string -- in the context of the configuration. Raises
        Kconfig_Syntax_Error if syntax errors are detected in 's'.

        For example, if FOO and BAR are tristate symbols at least one of which
        has the value "y", then config.eval("y && (FOO || BAR)") => "y"

        This functions always yields a tristate value. To get the value of
        non-bool, non-tristate symbols, use Symbol.get_value().

        The result of this function is consistent with how evaluation works for
        conditional expressions in the configuration as well as in the C
        implementation. "m" and m are rewritten as '"m" && MODULES' and 'm &&
        MODULES', respectively, and a result of "m" will get promoted to "y" if
        we're running without modules."""
        return self._eval_expr(self._parse_expr(self._tokenize(s, True), # Feed
                                                None, # Current symbol or choice
                                                s))   # line

    def get_config_header(self):
        """Returns the (uncommented) textual header of the .config file most
        recently loaded with load_config(). Returns None if no .config file has
        been loaded or if the most recently loaded .config file has no header.
        The header comprises all lines up to but not including the first line
        that either

        1. Does not start with "#"
        2. Has the form "# CONFIG_FOO is not set."
        """
        return self.config_header

    def get_base_dir(self):
        """Returns the base directory relative to which 'source' statements
        will work, passed as an argument to Config.__init__()."""
        return self.base_dir

    def set_print_warnings(self, print_warnings):
        """Determines whether warnings related to this configuration (for
        things like attempting to assign illegal values to symbols with
        Symbol.set_user_value()) should be printed to stderr.

        print_warnings -- True if warnings should be
                          printed, otherwise False."""
        self.print_warnings = print_warnings

    def set_print_undef_assign(self, print_undef_assign):
        """Determines whether informational messages related to assignments to
        undefined symbols should be printed to stderr for this configuration.

        print_undef_assign -- If True, such messages will be printed."""
        self.print_undef_assign = print_undef_assign

    def __getitem__(self, key):
        """Returns the symbol with name 'name'. Raises KeyError if the symbol
        does not appear in the configuration."""
        return self.syms[key]

    def __iter__(self):
        """Convenience function for iterating over the set of all defined
        symbols in the configuration, used like

        for sym in conf:
            ...

        The iteration happens in the order of definition within the Kconfig
        configuration files. Symbols only referred to but not defined will not
        be included, nor will the special symbols n, m, and y. If you want to
        include such symbols as well, see config.get_symbols()."""
        return iter(self.kconfig_syms)

    def unset_user_values(self):
        """Resets the values of all symbols, as if Config.load_config() or
        Symbol.set_user_value() had never been called."""
        for sym in self.syms.itervalues():
            sym._unset_user_value_no_recursive_invalidate()

    def __str__(self):
        """Returns a string containing various information about the Config."""
        return _sep_lines("Configuration",
                          "File                                   : " + self.filename,
                          "Base directory                         : " + self.base_dir,
                          "Value of $ARCH at creation time        : " +
                            ("(not set)" if self.arch is None else self.arch),
                          "Value of $SRCARCH at creation time     : " +
                            ("(not set)" if self.srcarch is None else self.srcarch),
                          "Source tree (derived from $srctree;",
                          "defaults to '.' if $srctree isn't set) : " + self.srctree,
                          "Most recently loaded .config           : " +
                            ("(no .config loaded)" if self.config_filename is None else
                             self.config_filename),
                          "Print warnings                         : " +
                            bool_str[self.print_warnings],
                          "Print assignments to undefined symbols : " +
                            bool_str[self.print_undef_assign])


    #
    # Private methods
    #

    def _invalidate_all(self):
        for sym in self.syms.itervalues():
            sym._invalidate()

    def _tokenize(self,
                  s,
                  for_eval = False,
                  filename = None,
                  linenr = None):
        """Returns a _Feed instance containing tokens derived from the string
        's'. Registers any new symbols encountered (via _sym_lookup()).

        (I experimented with a pure regular expression implementation, but it
        came out slower, less readable, and wouldn't have been as flexible.)

        for_eval -- True when parsing an expression for a call to
                    Config.eval(), in which case we should not treat the first
                    token specially nor register new symbols."""
        s = s.lstrip()
        if s == "" or s[0] == "#":
            return _Feed([])

        if for_eval:
            i = 0 # The current index in the string being tokenized
            previous = None # The previous token seen
            tokens = []
        else:
            # The initial word on a line is parsed specially. Let
            # command_chars = [A-Za-z0-9_]. Then
            #  - leading non-command_chars characters on the line are ignored, and
            #  - the first token consists the following one or more command_chars
            #    characters.
            # This is why things like "----help--" are accepted.

            initial_token_match = initial_token_re.match(s)
            if initial_token_match is None:
                return _Feed([])
            # The current index in the string being tokenized
            i = initial_token_match.end()

            keyword = keywords.get(initial_token_match.group(1))
            if keyword is None:
                # We expect a keyword as the first token
                _tokenization_error(s, len(s), filename, linenr)
            if keyword == T_HELP:
                # Avoid junk after "help", e.g. "---", being registered as a
                # symbol
                return _Feed([T_HELP])
            tokens = [keyword]
            previous = keyword

        # _tokenize() is a hotspot during parsing, and this speeds things up a
        # bit
        strlen = len(s)
        append = tokens.append

        # Main tokenization loop. (Handles tokens past the first one.)
        while i < strlen:
            # Test for an identifier/keyword preceded by whitespace first; this
            # is the most common case.
            id_keyword_match = id_keyword_re.match(s, i)
            if id_keyword_match:
                # We have an identifier or keyword. The above also stripped any
                # whitespace for us.
                name = id_keyword_match.group(1)
                # Jump past it
                i = id_keyword_match.end()

                # Keyword?
                keyword = keywords.get(name)
                if keyword is not None:
                    append(keyword)
                # What would ordinarily be considered a name is treated as a
                # string after certain tokens.
                elif previous in string_lex:
                    append(name)
                else:
                    # We're dealing with a symbol. _sym_lookup() will take care
                    # of allocating a new Symbol instance if it's the first
                    # time we see it.
                    sym = self._sym_lookup(name, not for_eval)

                    if previous == T_CONFIG or previous == T_MENUCONFIG:
                        # If the previous token is T_(MENU)CONFIG
                        # ("(menu)config"), we're tokenizing the first line of
                        # a symbol definition, and should remember this as a
                        # location where the symbol is defined.
                        sym.def_locations.append((filename, linenr))
                    else:
                        # Otherwise, it's a reference to the symbol
                        sym.ref_locations.append((filename, linenr))

                    append(sym)

            else:
                # This restrips whitespace that could have been stripped in the
                # regex above, but it's worth it since identifiers/keywords are
                # more common
                s = s[i:].lstrip()
                if s == "":
                    break
                strlen = len(s)
                i = 0
                c = s[0]

                # String literal (constant symbol)
                if c == '"' or c == "'":
                    i += 1

                    if "\\" in s:
                        # Slow path: This could probably be sped up, but it's a
                        # very unusual case anyway.
                        quote = c
                        value = ""
                        while 1:
                            if i >= strlen:
                                _tokenization_error(s, strlen, filename,
                                                    linenr)
                            c = s[i]
                            if c == quote:
                                break
                            if c == "\\":
                                if i + 1 >= strlen:
                                    _tokenization_error(s, strlen, filename,
                                                        linenr)
                                value += s[i + 1]
                                i += 2
                            else:
                                value += c
                                i += 1
                        i += 1
                        append(value)
                    else:
                        # Fast path: If the string contains no backslashes (almost
                        # always) we can simply look for the matching quote.
                        end = s.find(c, i)
                        if end == -1:
                            _tokenization_error(s, strlen, filename, linenr)
                        append(s[i:end])
                        i = end + 1

                elif c == "&":
                    if i + 1 >= strlen:
                        # Invalid characters are ignored
                        continue
                    if s[i + 1] != "&":
                        # Invalid characters are ignored
                        i += 1
                        continue
                    append(T_AND)
                    i += 2

                elif c == "|":
                    if i + 1 >= strlen:
                        # Invalid characters are ignored
                        continue
                    if s[i + 1] != "|":
                        # Invalid characters are ignored
                        i += 1
                        continue
                    append(T_OR)
                    i += 2

                elif c == "!":
                    if i + 1 >= strlen:
                        _tokenization_error(s, strlen, filename, linenr)
                    if s[i + 1] == "=":
                        append(T_UNEQUAL)
                        i += 2
                    else:
                        append(T_NOT)
                        i += 1

                elif c == "=":
                    append(T_EQUAL)
                    i += 1

                elif c == "(":
                    append(T_OPEN_PAREN)
                    i += 1

                elif c == ")":
                    append(T_CLOSE_PAREN)
                    i += 1

                elif c == "#":
                    break

                else:
                    # Invalid characters are ignored
                    i += 1
                    continue

            previous = tokens[-1]

        return _Feed(tokens)

    #
    # Parsing
    #

    # Expression grammar:
    #
    # <expr> -> <symbol>
    #           <symbol> '=' <symbol>
    #           <symbol> '!=' <symbol>
    #           '(' <expr> ')'
    #           '!' <expr>
    #           <expr> '&&' <expr>
    #           <expr> '||' <expr>

    def _parse_expr(self,
                    feed,
                    cur_sym_or_choice,
                    line,
                    filename = None,
                    linenr = None,
                    transform_m = True):
        """Parse an expression from the tokens in 'feed' using a simple
        top-down approach. The result has the form (<operator>, <list
        containing parsed operands>).

        feed -- _Feed instance containing the tokens for the expression.

        cur_sym_or_choice -- The symbol or choice currently being parsed, or
                             None if we're not parsing a symbol or choice.
                             Used for recording references to symbols.

        line -- The line containing the expression being parsed.

        filename (default: None) -- The file containing the expression.

        linenr (default: None) -- The line number containing the expression.

        transform_m (default: False) -- Determines if 'm' should be rewritten to
                                        'm && MODULES' -- see
                                        parse_val_and_cond()."""

        # Use instance variables to avoid having to pass these as arguments
        # through the top-down parser in _parse_expr_2(), which is tedious and
        # obfuscates the code. A profiler run shows no noticeable performance
        # difference.
        self.parse_expr_cur_sym_or_choice = cur_sym_or_choice
        self.parse_expr_line = line
        self.parse_expr_filename = filename
        self.parse_expr_linenr = linenr
        self.parse_expr_transform_m = transform_m

        return self._parse_expr_2(feed)

    def _parse_expr_2(self, feed):
        or_terms = [self._parse_or_term(feed)]
        # Keep parsing additional terms while the lookahead is '||'
        while feed.check(T_OR):
            or_terms.append(self._parse_or_term(feed))

        return or_terms[0] if len(or_terms) == 1 else (OR, or_terms)

    def _parse_or_term(self, feed):
        and_terms = [self._parse_factor(feed)]
        # Keep parsing additional terms while the lookahead is '&&'
        while feed.check(T_AND):
            and_terms.append(self._parse_factor(feed))

        return and_terms[0] if len(and_terms) == 1 else (AND, and_terms)

    def _parse_factor(self, feed):
        if feed.check(T_OPEN_PAREN):
            expr_parse = self._parse_expr_2(feed)

            if not feed.check(T_CLOSE_PAREN):
                _parse_error(self.parse_expr_line,
                             "missing end parenthesis.",
                             self.parse_expr_filename,
                             self.parse_expr_linenr)

            return expr_parse

        if feed.check(T_NOT):
            return (NOT, self._parse_factor(feed))

        sym_or_string = feed.get_next()

        if not isinstance(sym_or_string, (Symbol, str)):
            _parse_error(self.parse_expr_line,
                         "malformed expression.",
                         self.parse_expr_filename,
                         self.parse_expr_linenr)

        if self.parse_expr_cur_sym_or_choice is not None and \
           isinstance(sym_or_string, Symbol):
            self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string)

        next_token = feed.peek_next()

        # For conditional expressions ('depends on <expr>', '... if <expr>',
        # etc.), "m" and m are rewritten to "m" && MODULES.
        if next_token != T_EQUAL and next_token != T_UNEQUAL:
            if self.parse_expr_transform_m and (sym_or_string is self.m or
                                                sym_or_string == "m"):
                return (AND, ["m", self._sym_lookup("MODULES")])
            return sym_or_string

        relation = EQUAL if (feed.get_next() == T_EQUAL) else UNEQUAL
        sym_or_string_2 = feed.get_next()

        if self.parse_expr_cur_sym_or_choice is not None and \
           isinstance(sym_or_string_2, Symbol):
            self.parse_expr_cur_sym_or_choice.referenced_syms.add(sym_or_string_2)

        if sym_or_string is self.m:
            sym_or_string = "m"

        if sym_or_string_2 is self.m:
            sym_or_string_2 = "m"

        return (relation, sym_or_string, sym_or_string_2)

    def _parse_file(self, filename, parent, deps, visible_if_deps, res = None):
        """Parse the Kconfig file 'filename'. The result is a _Block with all
        items from the file. See _parse_block() for the meaning of the
        parameters."""
        line_feeder = _FileFeed(_get_lines(filename), filename)
        return self._parse_block(line_feeder, None, parent, deps, visible_if_deps, res)

    def _parse_block(self, line_feeder, end_marker, parent, deps,
                     visible_if_deps = None, res = None):
        """Parses a block, which is the contents of either a file or an if,
        menu, or choice statement. The result is a _Block with the items from
        the block.

        end_marker -- The token that ends the block, e.g. T_ENDIF ("endif") for
                      if's. None for files.

        parent -- The enclosing menu, choice or if, or None if we're at the top
                  level.

        deps -- Dependencies from enclosing menus, choices and if's.

        visible_if_deps (default: None) -- 'visible if' dependencies from
                        enclosing menus.

        res (default: None) -- The _Block to add items to. If None, a new
                               _Block is created to hold the items."""

        block = _Block() if res is None else res

        filename = line_feeder.get_filename()

        while 1:

            # Do we already have a tokenized line that we determined wasn't
            # part of whatever we were parsing earlier? See comment in
            # Config.__init__().
            if self.end_line is not None:
                assert self.end_line_tokens is not None
                tokens = self.end_line_tokens
                tokens.go_to_start()

                line = self.end_line
                linenr = line_feeder.get_linenr()

                self.end_line = None
                self.end_line_tokens = None

            else:
                line = line_feeder.get_next()
                if line is None:
                    if end_marker is not None:
                        raise Kconfig_Syntax_Error, (
                                "Unexpected end of file {0}."
                                .format(line_feeder.get_filename()))
                    return block

                linenr = line_feeder.get_linenr()

                tokens = self._tokenize(line, False, filename, linenr)

            if tokens.is_empty():
                continue

            t0 = tokens.get_next()

            # Have we reached the end of the block?
            if t0 == end_marker:
                return block

            if t0 == T_CONFIG or t0 == T_MENUCONFIG:
                # The tokenizer will automatically allocate a new Symbol object
                # for any new names it encounters, so we don't need to worry
                # about that here.
                sym = tokens.get_next()

                # Symbols defined in multiple places get the parent of their
                # first definition. However, for symbols whose parents are choice
                # statements, the choice statement takes precedence.
                if not sym.is_defined_ or isinstance(parent, Choice):
                    sym.parent = parent

                sym.is_defined_ = True

                self.kconfig_syms.append(sym)
                block.add_item(sym)

                self._parse_properties(line_feeder, sym, deps, visible_if_deps)

            elif t0 == T_MENU:
                menu = Menu()
                self.menus.append(menu)
                menu.config = self
                menu.parent = parent
                menu.title = tokens.get_next()

                menu.filename = filename
                menu.linenr = linenr

                # Parse properties and contents
                self._parse_properties(line_feeder, menu, deps, visible_if_deps)
                menu.block = self._parse_block(line_feeder,
                                               T_ENDMENU,
                                               menu,
                                               menu.dep_expr,
                                               _make_and(visible_if_deps,
                                                         menu.visible_if_expr))

                block.add_item(menu)

            elif t0 == T_IF:
                # If statements are treated as syntactic sugar for adding
                # dependencies to enclosed items and do not have an explicit
                # object representation.

                dep_expr = self._parse_expr(tokens, None, line, filename, linenr)
                self._parse_block(line_feeder,
                                  T_ENDIF,
                                  parent,
                                  _make_and(dep_expr, deps),
                                  visible_if_deps,
                                  block) # Add items to the same block

            elif t0 == T_CHOICE:
                # We support named choices
                already_defined = False
                name = None
                if len(tokens) > 1 and isinstance(tokens[1], str):
                    name = tokens[1]
                    already_defined = name in self.named_choices

                if already_defined:
                    choice = self.named_choices[name]
                else:
                    choice = Choice()
                    self.choices.append(choice)
                    if name is not None:
                        choice.name = name
                        self.named_choices[name] = choice

                choice.config = self
                choice.parent = parent

                choice.def_locations.append((filename, linenr))

                # Parse properties and contents
                self._parse_properties(line_feeder, choice, deps, visible_if_deps)
                choice.block = self._parse_block(line_feeder,
                                                 T_ENDCHOICE,
                                                 choice,
                                                 None,
                                                 visible_if_deps)

                choice._determine_actual_symbols()

                # If no type is set for the choice, its type is that of the first
                # choice item
                if choice.type == UNKNOWN:
                    for item in choice.get_symbols():
                        if item.type != UNKNOWN:
                            choice.type = item.type
                            break

                # Each choice item of UNKNOWN type gets the type of the choice
                for item in choice.get_symbols():
                    if item.type == UNKNOWN:
                        item.type = choice.type

                # For named choices defined in multiple locations, only record
                # at the first definition
                if not already_defined:
                    block.add_item(choice)

            elif t0 == T_COMMENT:
                comment = Comment()
                comment.config = self
                comment.parent = parent

                comment.filename = filename
                comment.linenr = linenr

                comment.text = tokens.get_next()
                self._parse_properties(line_feeder, comment, deps, visible_if_deps)

                block.add_item(comment)
                self.comments.append(comment)

            elif t0 == T_SOURCE:
                kconfig_file = tokens.get_next()
                exp_kconfig_file = self._expand_sym_refs(kconfig_file)
                f = os.path.join(self.base_dir, exp_kconfig_file)

                if not os.path.exists(f):
                    raise IOError, ('{0}:{1}: sourced file "{2}" (expands to\n'
                                    '"{3}") not found. Perhaps base_dir\n'
                                    '(argument to Config.__init__(), currently\n'
                                    '"{4}") is set to the wrong value.'
                                    .format(filename,
                                            linenr,
                                            kconfig_file,
                                            exp_kconfig_file,
                                            self.base_dir))

                # Add items to the same block
                self._parse_file(f, parent, deps, visible_if_deps, block)

            elif t0 == T_MAINMENU:
                text = tokens.get_next()

                if self.mainmenu_text is not None:
                    self._warn("overriding 'mainmenu' text. "
                               'Old value: "{0}", new value: "{1}".'
                                .format(self.mainmenu_text, text),
                               filename,
                               linenr)

                self.mainmenu_text = text

            else:
                _parse_error(line, "unrecognized construct.", filename, linenr)

    def _parse_properties(self, line_feeder, stmt, deps, visible_if_deps):
        """Parsing of properties for symbols, menus, choices, and comments."""

        def parse_val_and_cond(tokens, line, filename, linenr):
            """Parses '<expr1> if <expr2>' constructs, where the 'if' part is
            optional. Returns a tuple containing the parsed expressions, with
            None as the second element if the 'if' part is missing."""
            val = self._parse_expr(tokens, stmt, line, filename, linenr, False)

            if tokens.check(T_IF):
                return (val, self._parse_expr(tokens, stmt, line, filename, linenr))

            return (val, None)

        # In case the symbol is defined in multiple locations, we need to
        # remember what prompts, defaults, and selects are new for this
        # definition, as "depends on" should only apply to the local
        # definition.
        new_prompt = None
        new_def_exprs = []
        new_selects = []

        # Dependencies from 'depends on' statements
        depends_on_expr = None

        while 1:
            line = line_feeder.get_next()
            if line is None:
                break

            filename = line_feeder.get_filename()
            linenr = line_feeder.get_linenr()

            tokens = self._tokenize(line, False, filename, linenr)

            if tokens.is_empty():
                continue

            t0 = tokens.get_next()

            if t0 == T_HELP:
                # Find first non-empty line and get its indentation

                line_feeder.remove_while(str.isspace)
                line = line_feeder.get_next()

                if line is None:
                    stmt.help = ""
                    break

                indent = _indentation(line)

                # If the first non-empty lines has zero indent, there is no
                # help text
                if indent == 0:
                    stmt.help = ""
                    line_feeder.go_back()
                    break

                help_lines = [_deindent(line, indent)]

                # The help text goes on till the first non-empty line with less
                # indent
                while 1:
                    line = line_feeder.get_next()
                    if (line is None) or \
                       (not line.isspace() and _indentation(line) < indent):
                        stmt.help = "".join(help_lines)
                        break

                    help_lines.append(_deindent(line, indent))

                if line is None:
                    break

                line_feeder.go_back()

            elif t0 == T_PROMPT:
                # 'prompt' properties override each other within a single
                # definition of a symbol, but additional prompts can be added
                # by defining the symbol multiple times; hence 'new_prompt'
                # instead of 'prompt'.
                new_prompt = parse_val_and_cond(tokens, line, filename, linenr)

            elif t0 == T_DEFAULT:
                new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))

            elif t0 == T_DEPENDS:
                if not tokens.check(T_ON):
                    _parse_error(line, 'expected "on" after "depends".', filename, linenr)

                parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)

                if isinstance(stmt, (Menu, Comment)):
                    stmt.dep_expr = _make_and(stmt.dep_expr, parsed_deps)
                else:
                    depends_on_expr = _make_and(depends_on_expr, parsed_deps)

            elif t0 == T_VISIBLE:
                if not tokens.check(T_IF):
                    _parse_error(line, 'expected "if" after "visible".', filename, linenr)
                if not isinstance(stmt, Menu):
                    _parse_error(line,
                                 "'visible if' is only valid for menus.",
                                 filename,
                                 linenr)

                parsed_deps = self._parse_expr(tokens, stmt, line, filename, linenr)
                stmt.visible_if_expr = _make_and(stmt.visible_if_expr, parsed_deps)

            elif t0 == T_SELECT:
                target = tokens.get_next()

                stmt.referenced_syms.add(target)
                stmt.selected_syms.add(target)

                if tokens.check(T_IF):
                    new_selects.append((target,
                                        self._parse_expr(tokens, stmt, line, filename, linenr)))
                else:
                    new_selects.append((target, None))

            elif t0 in (T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING):
                stmt.type = token_to_type[t0]

                if len(tokens) > 1:
                    new_prompt = parse_val_and_cond(tokens, line, filename, linenr)

            elif t0 == T_RANGE:
                lower = tokens.get_next()
                upper = tokens.get_next()
                stmt.referenced_syms.add(lower)
                stmt.referenced_syms.add(upper)

                if tokens.check(T_IF):
                    stmt.ranges.append((lower, upper,
                                        self._parse_expr(tokens, stmt, line, filename, linenr)))
                else:
                    stmt.ranges.append((lower, upper, None))

            elif t0 == T_DEF_BOOL:
                stmt.type = BOOL

                if len(tokens) > 1:
                    new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))

            elif t0 == T_DEF_TRISTATE:
                stmt.type = TRISTATE

                if len(tokens) > 1:
                    new_def_exprs.append(parse_val_and_cond(tokens, line, filename, linenr))

            elif t0 == T_OPTIONAL:
                if not isinstance(stmt, Choice):
                    _parse_error(line,
                                 '"optional" is only valid for choices.',
                                 filename,
                                 linenr)
                stmt.optional = True

            elif t0 == T_OPTION:
                if tokens.check(T_ENV) and tokens.check(T_EQUAL):
                    env_var = tokens.get_next()

                    stmt.is_special_ = True
                    stmt.is_from_env = True

                    if env_var not in os.environ:
                        self._warn("""
The symbol {0} references the non-existent environment variable {1} and will
get the empty string as its value.

If you're using kconfiglib via 'make (i)scriptconfig' it should have set up the
environment correctly for you. If you still got this message, that might be an
error, and you should e-mail kconfiglib@gmail.com.
."""                               .format(stmt.name, env_var),
                                   filename,
                                   linenr)

                        stmt.cached_value = ""
                    else:
                        stmt.cached_value = os.environ[env_var]

                elif tokens.check(T_DEFCONFIG_LIST):
                    self.defconfig_sym = stmt

                elif tokens.check(T_MODULES):
                    self._warn("the 'modules' option is not supported. "
                               "Let me know if this is a problem for you; "
                               "it shouldn't be that hard to implement.",
                               filename,
                               linenr)

                else:
                    _parse_error(line, "unrecognized option.", filename, linenr)

            else:
                # See comment in Config.__init__()
                self.end_line = line
                self.end_line_tokens = tokens
                break

        # Propagate dependencies from enclosing menus and if's.

        # For menus and comments..
        if isinstance(stmt, (Menu, Comment)):
            stmt.orig_deps = stmt.dep_expr
            stmt.deps_from_containing = deps
            stmt.dep_expr = _make_and(stmt.dep_expr, deps)

            stmt.all_referenced_syms = \
              stmt.referenced_syms | _get_expr_syms(deps)

        # For symbols and choices..
        else:

            # See comment for 'menu_dep'
            stmt.menu_dep = depends_on_expr

            # Propagate dependencies specified with 'depends on' to any new
            # default expressions, prompts, and selections. ("New" since a
            # symbol might be defined in multiple places and the dependencies
            # should only apply to the local definition.)

            new_def_exprs = [(val_expr, _make_and(cond_expr, depends_on_expr))
                             for (val_expr, cond_expr) in new_def_exprs]

            new_selects = [(target, _make_and(cond_expr, depends_on_expr))
                           for (target, cond_expr) in new_selects]

            if new_prompt is not None:
                prompt, cond_expr = new_prompt

                # 'visible if' dependencies from enclosing menus get propagated
                # to prompts
                if visible_if_deps is not None:
                    cond_expr = _make_and(cond_expr, visible_if_deps)

                new_prompt = (prompt, _make_and(cond_expr, depends_on_expr))

            # We save the original expressions -- before any menu and if
            # conditions have been propagated -- so these can be retrieved
            # later.

            stmt.orig_def_exprs.extend(new_def_exprs)
            if new_prompt is not None:
                stmt.orig_prompts.append(new_prompt)

            # Only symbols can select
            if isinstance(stmt, Symbol):
                stmt.orig_selects.extend(new_selects)

            # Save dependencies from enclosing menus and if's
            stmt.deps_from_containing = deps

            # The set of symbols referenced directly by the symbol/choice plus
            # all symbols referenced by enclosing menus and if's.
            stmt.all_referenced_syms = \
              stmt.referenced_syms | _get_expr_syms(deps)

            # Propagate dependencies from enclosing menus and if's

            stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
                                   for (val_expr, cond_expr) in new_def_exprs])

            for (target, cond) in new_selects:
                target.rev_dep = _make_or(target.rev_dep,
                                          _make_and(stmt,
                                                    _make_and(cond, deps)))

            if new_prompt is not None:
                prompt, cond_expr = new_prompt
                stmt.prompts.append((prompt, _make_and(cond_expr, deps)))

    #
    # Symbol table manipulation
    #

    def _sym_lookup(self, name, add_sym_if_not_exists = True):
        """Fetches the symbol 'name' from the symbol table, optionally adding
        it if it does not exist (this is usually what we want)."""
        if name in self.syms:
            return self.syms[name]

        new_sym = Symbol()
        new_sym.config = self
        new_sym.name = name

        if add_sym_if_not_exists:
            self.syms[name] = new_sym
        else:
            # This warning is generated while evaluating an expression
            # containing undefined symbols using Config.eval()
            self._warn("no symbol {0} in configuration".format(name))

        return new_sym

    #
    # Evaluation of symbols and expressions
    #

    def _eval_expr(self, expr):
        """Evaluates an expression and returns one of the tristate values "n",
        "m" or "y"."""
        res = self._eval_expr_2(expr)

        # Promote "m" to "y" if we're running without modules. Internally, "m"
        # is often rewritten to "m" && MODULES by both the C implementation and
        # kconfiglib, which takes care of cases where "m" should be false if
        # we're running without modules.
        if res == "m" and not self._has_modules():
            return "y"

        return res

    def _eval_expr_2(self, expr):
        if expr is None:
            return "y"

        if isinstance(expr, Symbol):
            # Non-bool/tristate symbols are always "n" in a tristate sense,
            # regardless of their value
            if expr.type != BOOL and expr.type != TRISTATE:
                return "n"
            return expr.get_value()

        if isinstance(expr, str):
            return expr if (expr == "y" or expr == "m") else "n"

        first_expr = expr[0]

        if first_expr == OR:
            res = "n"

            for subexpr in expr[1]:
                ev = self._eval_expr_2(subexpr)

                # Return immediately upon discovering a "y" term
                if ev == "y":
                    return "y"

                if ev == "m":
                    res = "m"

            # 'res' is either "n" or "m" here; we already handled the
            # short-circuiting "y" case in the loop.
            return res

        if first_expr == AND:
            res = "y"

            for subexpr in expr[1]:
                ev = self._eval_expr_2(subexpr)

                # Return immediately upon discovering an "n" term
                if ev == "n":
                    return "n"

                if ev == "m":
                    res = "m"

            # 'res' is either "m" or "y" here; we already handled the
            # short-circuiting "n" case in the loop.
            return res

        if first_expr == NOT:
            ev = self._eval_expr_2(expr[1])

            if ev == "y":
                return "n"

            return "y" if (ev == "n") else "m"

        if first_expr == EQUAL:
            return "y" if (self._get_str_value(expr[1]) ==
                           self._get_str_value(expr[2])) else "n"

        if first_expr == UNEQUAL:
            return "y" if (self._get_str_value(expr[1]) !=
                           self._get_str_value(expr[2])) else "n"

        _internal_error("Internal error while evaluating expression: "
                        "unknown operation {0}.".format(first_expr))

    def _get_str_value(self, obj):
        if isinstance(obj, str):
            return obj
        # obj is a Symbol
        return obj.get_value()

    def _eval_min(self, e1, e2):
        e1_eval = self._eval_expr(e1)
        e2_eval = self._eval_expr(e2)

        return e1_eval if tri_less(e1_eval, e2_eval) else e2_eval

    def _eval_max(self, e1, e2):
        e1_eval = self._eval_expr(e1)
        e2_eval = self._eval_expr(e2)

        return e1_eval if tri_greater(e1_eval, e2_eval) else e2_eval

    #
    # Methods related to the MODULES symbol
    #

    def _has_modules(self):
        modules_sym = self.syms.get("MODULES")
        return (modules_sym is not None) and (modules_sym.get_value() == "y")

    #
    # Dependency tracking
    #

    def _build_dep(self):
        """Populates the Symbol.dep sets, linking the symbol to the symbols
        that immediately depend on it in the sense that changing the value of
        the symbol might affect the values of those other symbols. This is used
        for caching/invalidation purposes. The calculated sets might be larger
        than necessary as we don't do any complicated analysis of the
        expressions."""
        for sym in self.syms.itervalues():
            sym.dep = set()

        # Adds 'sym' as a directly dependent symbol to all symbols that appear
        # in the expression 'e'
        def add_expr_deps(e, sym):
            for s in _get_expr_syms(e):
                s.dep.add(sym)

        # The directly dependent symbols of a symbol are:
        #  - Any symbols whose prompts, default values, rev_dep (select
        #    condition), or ranges depend on the symbol
        #  - Any symbols that belong to the same choice statement as the symbol
        #    (these won't be included in 'dep' as that makes the dependency
        #    graph unwieldy, but Symbol._get_dependent() will include them)
        #  - Any symbols in a choice statement that depends on the symbol
        for sym in self.syms.itervalues():
            for (_, e) in sym.prompts:
                add_expr_deps(e, sym)

            for (v, e) in sym.def_exprs:
                add_expr_deps(v, sym)
                add_expr_deps(e, sym)

            add_expr_deps(sym.rev_dep, sym)

            for (l, u, e) in sym.ranges:
                add_expr_deps(l, sym)
                add_expr_deps(u, sym)
                add_expr_deps(e, sym)

            if sym.is_choice_symbol_:
                choice = sym.parent

                for (_, e) in choice.prompts:
                    add_expr_deps(e, sym)

                for (_, e) in choice.def_exprs:
                    add_expr_deps(e, sym)

    def _expr_val_str(self, expr, no_value_str = "(none)", get_val_instead_of_eval = False):
        # Since values are valid expressions, _expr_to_str() will get a nice
        # string representation for those as well.

        if expr is None:
            return no_value_str

        if get_val_instead_of_eval:
            if isinstance(expr, str):
                return _expr_to_str(expr)
            val = expr.get_value()
        else:
            val = self._eval_expr(expr)

        return "{0} (value: {1})".format(_expr_to_str(expr), _expr_to_str(val))

    def _expand_sym_refs(self, s):
        """Expands $-references to symbols in 's' to symbol values, or to the
        empty string for undefined symbols."""

        while 1:
            sym_ref_re_match = sym_ref_re.search(s)
            if sym_ref_re_match is None:
                return s

            sym_name = sym_ref_re_match.group(0)[1:]
            sym = self.syms.get(sym_name)
            expansion = "" if sym is None else sym.get_value()

            s = s[:sym_ref_re_match.start()] + \
                expansion + \
                s[sym_ref_re_match.end():]

    def _get_sym_or_choice_str(self, sc):
        """Symbols and choices have many properties in common, so we factor out
        common __str__() stuff here. "sc" is short for "symbol or choice"."""

        # As we deal a lot with string representations here, use some
        # convenient shorthand:
        s = _expr_to_str

        #
        # Common symbol/choice properties
        #

        user_value_str = "(no user value)" if sc.user_val is None else s(sc.user_val)

        visibility_str = s(sc.get_visibility())

        # Build prompts string
        if sc.prompts == []:
            prompts_str = " (no prompts)"
        else:
            prompts_str_rows = []

            for (prompt, cond_expr) in sc.orig_prompts:
                if cond_expr is None:
                    prompts_str_rows.append(' "{0}"'.format(prompt))
                else:
                    prompts_str_rows.append(' "{0}" if '.format(prompt) +
                                            self._expr_val_str(cond_expr))

            prompts_str = "\n".join(prompts_str_rows)

        # Build locations string
        if sc.def_locations == []:
            locations_str = "(no locations)"
        else:
            locations_str = " ".join(["{0}:{1}".format(filename, linenr) for
                                      (filename, linenr) in sc.def_locations])

        # Build additional-dependencies-from-menus-and-if's string
        additional_deps_str = " " + self._expr_val_str(sc.deps_from_containing,
                                                       "(no additional dependencies)")

        #
        # Symbol-specific stuff
        #

        if isinstance(sc, Symbol):

            # Build value string
            value_str = s(sc.get_value())

            # Build ranges string
            if isinstance(sc, Symbol):
                if sc.ranges == []:
                    ranges_str = " (no ranges)"
                else:
                    ranges_str_rows = []

                    for (l, u, cond_expr) in sc.ranges:
                        if cond_expr is None:
                            ranges_str_rows.append(" [{0}, {1}]".format(s(l), s(u)))
                        else:
                            ranges_str_rows.append(" [{0}, {1}] if {2}"
                                                   .format(s(l), s(u), self._expr_val_str(cond_expr)))

                    ranges_str = "\n".join(ranges_str_rows)

            # Build default values string
            if sc.def_exprs == []:
                defaults_str = " (no default values)"
            else:
                defaults_str_rows = []

                for (val_expr, cond_expr) in sc.orig_def_exprs:
                    row_str = " " + self._expr_val_str(val_expr, "(none)", sc.type == STRING)
                    defaults_str_rows.append(row_str)
                    defaults_str_rows.append("  Condition: " + self._expr_val_str(cond_expr))

                defaults_str = "\n".join(defaults_str_rows)

            # Build selects string
            if sc.orig_selects == []:
                selects_str = " (no selects)"
            else:
                selects_str_rows = []

                for (target, cond_expr) in sc.orig_selects:
                    if cond_expr is None:
                        selects_str_rows.append(" {0}".format(target.name))
                    else:
                        selects_str_rows.append(" {0} if ".format(target.name) +
                                                self._expr_val_str(cond_expr))

                selects_str = "\n".join(selects_str_rows)

            # Build reverse dependencies string
            if sc.rev_dep == "n":
                rev_dep_str = " (no reverse dependencies)"
            else:
                rev_dep_str = " " + self._expr_val_str(sc.rev_dep)

            res = _sep_lines("Symbol " + (sc.name if sc.name is not None else "(no name)"),
                             "Type           : " + typename[sc.type],
                             "Value          : " + value_str,
                             "User value     : " + user_value_str,
                             "Visibility     : " + visibility_str,
                             "Is choice item : " + bool_str[sc.is_choice_symbol_],
                             "Is defined     : " + bool_str[sc.is_defined_],
                             "Is from env.   : " + bool_str[sc.is_from_env],
                             "Is special     : " + bool_str[sc.is_special_] + "\n")

            if sc.ranges != []:
                res += _sep_lines("Ranges:",
                                  ranges_str + "\n")

            res += _sep_lines("Prompts:",
                              prompts_str,
                              "Default values:",
                              defaults_str,
                              "Selects:",
                              selects_str,
                              "Reverse dependencies:",
                              rev_dep_str,
                              "Additional dependencies from enclosing menus and if's:",
                              additional_deps_str,
                              "Locations: " + locations_str)

            return res

        #
        # Choice-specific stuff
        #

        # Build name string (for named choices)
        if sc.name is None:
            name_str = "(no name)"
        else:
            name_str = sc.name

        # Build selected symbol string
        sel = sc.get_selection()
        if sel is None:
            sel_str = "(no selection)"
        else:
            sel_str = sel.name

        # Build mode string
        mode_str = s(sc.get_mode())

        # Build default values string
        if sc.def_exprs == []:
            defaults_str = " (no default values)"
        else:
            defaults_str_rows = []

            for (sym, cond_expr) in sc.orig_def_exprs:
                if cond_expr is None:
                    defaults_str_rows.append(" {0}".format(sym.name))
                else:
                    defaults_str_rows.append(" {0} if ".format(sym.name) +
                                             self._expr_val_str(cond_expr))

            defaults_str = "\n".join(defaults_str_rows)

        # Build contained symbols string
        names = [sym.name for sym in sc.get_symbols()]

        if names == []:
            syms_string = "(empty)"
        else:
            syms_string = " ".join(names)

        return _sep_lines("Choice",
                          "Name (for named choices): " + name_str,
                          "Type            : " + typename[sc.type],
                          "Selected symbol : " + sel_str,
                          "User value      : " + user_value_str,
                          "Mode            : " + mode_str,
                          "Visibility      : " + visibility_str,
                          "Optional        : " + bool_str[sc.optional],
                          "Prompts:",
                          prompts_str,
                          "Defaults:",
                          defaults_str,
                          "Choice symbols:",
                          " " + syms_string,
                          "Additional dependencies from enclosing menus and if's:",
                          additional_deps_str,
                          "Locations: " + locations_str)

    def _expr_depends_on(self, expr, sym):
        """Reimplementation of expr_depends_symbol() from mconf.c. Used to
        determine if a submenu should be implicitly created, which influences what
        items inside choice statements are considered choice items."""
        if expr is None:
            return False

        def rec(expr):
            if isinstance(expr, str):
                return False

            if isinstance(expr, Symbol):
                return expr is sym

            e0 = expr[0]

            if e0 == EQUAL or e0 == UNEQUAL:
                return self._eq_to_sym(expr) is sym

            if e0 == AND:
                for and_expr in expr[1]:
                    if rec(and_expr):
                        return True

            return False

        return rec(expr)

    def _eq_to_sym(self, eq):
        """_expr_depends_on() helper. For (in)equalities of the form sym = y/m
        or sym != n, returns sym. For other (in)equalities, returns None."""
        relation, left, right = eq

        left  = self._transform_n_m_y(left)
        right = self._transform_n_m_y(right)

        # Make sure the symbol (if any) appears to the left
        if not isinstance(left, Symbol):
            left, right = right, left

        if not isinstance(left, Symbol):
            return None

        if (relation == EQUAL   and (right == "m" or right == "y")) or \
           (relation == UNEQUAL and right == "n"):
            return left

        return None

    def _transform_n_m_y(self, item):
        """_eq_to_sym() helper. Translates the symbols n, m, and y to their
        string equivalents."""
        if item is self.n:
            return "n"
        if item is self.m:
            return "m"
        if item is self.y:
            return "y"
        return item

    def _warn(self, msg, filename = None, linenr = None):
        """For printing warnings to stderr."""
        if self.print_warnings:
            self._warn_or_undef_assign(msg, WARNING, filename, linenr)

    def _undef_assign(self, msg, filename = None, linenr = None):
        """For printing informational messages related to assignments
        to undefined variables to stderr."""
        if self.print_undef_assign:
            self._warn_or_undef_assign(msg, UNDEF_ASSIGN, filename, linenr)

    def _warn_or_undef_assign(self, msg, msg_type, filename, linenr):
        if filename is not None:
            sys.stderr.write("{0}:".format(_clean_up_path(filename)))
        if linenr is not None:
            sys.stderr.write("{0}:".format(linenr))

        if msg_type == WARNING:
            sys.stderr.write("warning: ")
        elif msg_type == UNDEF_ASSIGN:
            sys.stderr.write("info: ")
        else:
            _internal_error('Internal error while printing warning: unknown warning type "{0}".'
                            .format(msg_type))

        sys.stderr.write(msg + "\n")

def _get_expr_syms(expr):
    """Returns the set() of symbols appearing in expr."""
    res = set()
    if expr is None:
        return res

    def rec(expr):
        if isinstance(expr, Symbol):
            res.add(expr)
            return

        if isinstance(expr, str):
            return

        e0 = expr[0]

        if e0 == OR or e0 == AND:
            for term in expr[1]:
                rec(term)

        elif e0 == NOT:
            rec(expr[1])

        elif e0 == EQUAL or e0 == UNEQUAL:
            _, v1, v2 = expr

            if isinstance(v1, Symbol):
                res.add(v1)

            if isinstance(v2, Symbol):
                res.add(v2)

        else:
            _internal_error("Internal error while fetching symbols from an "
                            "expression with token stream {0}.".format(expr))

    rec(expr)
    return res


#
# Construction of expressions
#

# These functions as well as the _eval_min/max() functions above equate
# None with "y", which is usually what we want, but needs to be kept in
# mind.

def _make_or(e1, e2):
    # Perform trivial simplification and avoid None's (which
    # correspond to y's)
    if e1 is None or e2 is None or \
       e1 == "y" or e2 == "y":
        return "y"

    if e1 == "n":
        return e2

    if e2 == "n":
        return e1

    # Prefer to merge/update argument list if possible instead of creating
    # a new OR node

    if isinstance(e1, tuple) and e1[0] == OR:
        if isinstance(e2, tuple) and e2[0] == OR:
            return (OR, e1[1] + e2[1])
        return (OR, e1[1] + [e2])

    if isinstance(e2, tuple) and e2[0] == OR:
        return (OR, e2[1] + [e1])

    return (OR, [e1, e2])

# Note: returns None if e1 == e2 == None

def _make_and(e1, e2):
    if e1 == "n" or e2 == "n":
        return "n"

    if e1 is None or e1 == "y":
        return e2

    if e2 is None or e2 == "y":
        return e1

    # Prefer to merge/update argument list if possible instead of creating
    # a new AND node

    if isinstance(e1, tuple) and e1[0] == AND:
        if isinstance(e2, tuple) and e2[0] == AND:
            return (AND, e1[1] + e2[1])
        return (AND, e1[1] + [e2])

    if isinstance(e2, tuple) and e2[0] == AND:
        return (AND, e2[1] + [e1])

    return (AND, [e1, e2])

#
# Constants and functions related to types, parsing, evaluation and printing,
# put globally to unclutter the Config class a bit.
#

# Tokens
(T_OR, T_AND, T_NOT,
 T_OPEN_PAREN, T_CLOSE_PAREN,
 T_EQUAL, T_UNEQUAL,
 T_MAINMENU, T_MENU, T_ENDMENU,
 T_SOURCE, T_CHOICE, T_ENDCHOICE,
 T_COMMENT, T_CONFIG, T_MENUCONFIG,
 T_HELP, T_IF, T_ENDIF, T_DEPENDS, T_ON,
 T_OPTIONAL, T_PROMPT, T_DEFAULT,
 T_BOOL, T_TRISTATE, T_HEX, T_INT, T_STRING,
 T_DEF_BOOL, T_DEF_TRISTATE,
 T_SELECT, T_RANGE, T_OPTION, T_ENV,
 T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(0, 38)

# Keyword to token map
keywords = {
        "mainmenu"       : T_MAINMENU,
        "menu"           : T_MENU,
        "endmenu"        : T_ENDMENU,
        "endif"          : T_ENDIF,
        "endchoice"      : T_ENDCHOICE,
        "source"         : T_SOURCE,
        "choice"         : T_CHOICE,
        "config"         : T_CONFIG,
        "comment"        : T_COMMENT,
        "menuconfig"     : T_MENUCONFIG,
        "help"           : T_HELP,
        "if"             : T_IF,
        "depends"        : T_DEPENDS,
        "on"             : T_ON,
        "optional"       : T_OPTIONAL,
        "prompt"         : T_PROMPT,
        "default"        : T_DEFAULT,
        "bool"           : T_BOOL,
        "boolean"        : T_BOOL,
        "tristate"       : T_TRISTATE,
        "int"            : T_INT,
        "hex"            : T_HEX,
        "def_bool"       : T_DEF_BOOL,
        "def_tristate"   : T_DEF_TRISTATE,
        "string"         : T_STRING,
        "select"         : T_SELECT,
        "range"          : T_RANGE,
        "option"         : T_OPTION,
        "env"            : T_ENV,
        "defconfig_list" : T_DEFCONFIG_LIST,
        "modules"        : T_MODULES,
        "visible"        : T_VISIBLE }

# Strings to use for True and False
bool_str = { False : "false", True : "true" }

# Tokens after which identifier-like lexemes are treated as strings. T_CHOICE
# is included to avoid symbols being registered for named choices.
string_lex = frozenset((T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING, T_CHOICE,
                        T_PROMPT, T_MENU, T_COMMENT, T_SOURCE, T_MAINMENU))

# Matches the initial token on a line; see _tokenize().
initial_token_re = re.compile(r"[^\w]*(\w+)")

# Matches an identifier/keyword optionally preceded by whitespace
id_keyword_re = re.compile(r"\s*([\w./-]+)")

# Regular expressions for parsing .config files
set_re   = re.compile(r"CONFIG_(\w+)=(.*)")
unset_re = re.compile(r"# CONFIG_(\w+) is not set")

# Regular expression for finding $-references to symbols in strings
sym_ref_re = re.compile(r"\$[A-Za-z_]+")

# Integers representing symbol types
UNKNOWN, BOOL, TRISTATE, STRING, HEX, INT = range(0, 6)

# Strings to use for types
typename = {
        UNKNOWN  : "unknown",
        BOOL     : "bool",
        TRISTATE : "tristate",
        STRING   : "string",
        HEX      : "hex",
        INT      : "int" }

# Token to type mapping
token_to_type = { T_BOOL     : BOOL,
                  T_TRISTATE : TRISTATE,
                  T_STRING   : STRING,
                  T_INT      : INT,
                  T_HEX      : HEX }

# Default values for symbols of different types (the value the symbol gets if
# it is not assigned a user value and none of its 'default' clauses kick in)
default_value = { BOOL     : "n",
                  TRISTATE : "n",
                  STRING   : "",
                  INT      : "",
                  HEX      : "" }

# Indicates that no item is selected in a choice statement
NO_SELECTION = 0

# Integers representing expression types
OR, AND, NOT, EQUAL, UNEQUAL = range(0, 5)

# Map from tristate values to integers
tri_to_int = { "n" : 0, "m" : 1, "y" : 2 }

# Printing-related stuff

op_to_str = { AND     : " && ",
              OR      : " || ",
              EQUAL   : " = ",
              UNEQUAL : " != " }

precedence = { OR : 0, AND : 1, NOT : 2 }

# Types of informational messages
WARNING = 0
UNDEF_ASSIGN = 1

def _intersperse(lst, op):
    """_expr_to_str() helper. Gets the string representation of each expression in lst
    and produces a list where op has been inserted between the elements."""
    if lst == []:
        return ""

    res = []

    def handle_sub_expr(expr):
        no_parens = isinstance(expr, (str, Symbol)) or \
                    expr[0] in (EQUAL, UNEQUAL) or \
                    precedence[op] <= precedence[expr[0]]
        if not no_parens:
            res.append("(")
        res.extend(_expr_to_str_rec(expr))
        if not no_parens:
            res.append(")")

    op_str = op_to_str[op]

    handle_sub_expr(lst[0])
    for expr in lst[1:]:
        res.append(op_str)
        handle_sub_expr(expr)

    return res

def _expr_to_str(expr):
    s = "".join(_expr_to_str_rec(expr))
    return s

def _sym_str_string(sym_or_str):
    if isinstance(sym_or_str, str):
        return '"{0}"'.format(sym_or_str)
    return sym_or_str.name

def _expr_to_str_rec(expr):
    if expr is None:
        return [""]

    if isinstance(expr, (Symbol, str)):
        return [_sym_str_string(expr)]

    e0 = expr[0]

    if e0 == OR or e0 == AND:
        return _intersperse(expr[1], expr[0])

    if e0 == NOT:
        need_parens = not isinstance(expr[1], (str, Symbol))

        res = ["!"]
        if need_parens:
            res.append("(")
        res.extend(_expr_to_str_rec(expr[1]))
        if need_parens:
            res.append(")")
        return res

    if e0 == EQUAL or e0 == UNEQUAL:
        return [_sym_str_string(expr[1]),
                op_to_str[expr[0]],
                _sym_str_string(expr[2])]

class _Block:

    """Represents a list of items (symbols, menus, choice statements and
    comments) appearing at the top-level of a file or witin a menu, choice or
    if statement."""

    def __init__(self):
        self.items = []

    def get_items(self):
        return self.items

    def add_item(self, item):
        self.items.append(item)

    def _make_conf(self):
        # Collect the substrings in a list and later use join() instead of +=
        # to build the final .config contents. With older Python versions, this
        # yields linear instead of quadratic complexity.
        strings = []
        for item in self.items:
            strings.extend(item._make_conf())

        return strings

    def add_depend_expr(self, expr):
        for item in self.items:
            item.add_depend_expr(expr)

class Item():

    """Base class for symbols and other Kconfig constructs. Subclasses are
    Symbol, Choice, Menu, and Comment."""

    def is_symbol(self):
        """Returns True if the item is a symbol, otherwise False. Short for
        isinstance(item, kconfiglib.Symbol)."""
        return isinstance(self, Symbol)

    def is_choice(self):
        """Returns True if the item is a choice, otherwise False. Short for
        isinstance(item, kconfiglib.Choice)."""
        return isinstance(self, Choice)

    def is_menu(self):
        """Returns True if the item is a menu, otherwise False. Short for
        isinstance(item, kconfiglib.Menu)."""
        return isinstance(self, Menu)

    def is_comment(self):
        """Returns True if the item is a comment, otherwise False. Short for
        isinstance(item, kconfiglib.Comment)."""
        return isinstance(self, Comment)

class _HasVisibility():

    """Base class for elements that have a "visibility" that acts as an upper
    limit on the values a user can set for them. Subclasses are Symbol and
    Choice (which supply some of the attributes)."""

    def __init__(self):
        self.cached_visibility = None
        self.prompts = []

    def _invalidate(self):
        self.cached_visibility = None

    def _get_visibility(self):
        if self.cached_visibility is None:
            vis = "n"
            for (prompt, cond_expr) in self.prompts:
                vis = self.config._eval_max(vis, cond_expr)

            if isinstance(self, Symbol) and self.is_choice_symbol_:
                vis = self.config._eval_min(vis, self.parent._get_visibility())

            # Promote "m" to "y" if we're dealing with a non-tristate
            if vis == "m" and self.type != TRISTATE:
                vis = "y"

            self.cached_visibility = vis

        return self.cached_visibility

class Symbol(Item, _HasVisibility):

    """Represents a configuration symbol - e.g. FOO for

    config FOO
        ..."""

    #
    # Public interface
    #

    def get_value(self):
        """Calculate and return the value of the symbol. See also
        Symbol.set_user_value()."""

        if self.cached_value is not None:
            return self.cached_value

        self.write_to_conf = False

        # As a quirk of Kconfig, undefined symbols get their name as their
        # value. This is why things like "FOO = bar" work for seeing if FOO has
        # the value "bar".
        if self.type == UNKNOWN:
            self.cached_value = self.name
            return self.name

        new_val = default_value[self.type]

        vis = self._get_visibility()

        if self.type == BOOL or self.type == TRISTATE:
            # The visibility and mode (modules-only or single-selection) of
            # choice items will be taken into account in self._get_visibility()

            if self.is_choice_symbol_:
                if vis != "n":
                    choice = self.parent
                    mode = choice.get_mode()

                    self.write_to_conf = (mode != "n")

                    if mode == "y":
                        new_val = "y" if (choice.get_selection() is self) else "n"
                    elif mode == "m":
                        if self.user_val == "m" or self.user_val == "y":
                            new_val = "m"

            else:
                use_defaults = True

                if vis != "n":
                    # If the symbol is visible and has a user value, use that.
                    # Otherwise, look at defaults.
                    self.write_to_conf = True

                    if self.user_val is not None:
                        new_val = self.config._eval_min(self.user_val, vis)
                        use_defaults = False

                if use_defaults:
                    for (val_expr, cond_expr) in self.def_exprs:
                        cond_eval = self.config._eval_expr(cond_expr)

                        if cond_eval != "n":
                            self.write_to_conf = True
                            new_val = self.config._eval_min(val_expr, cond_eval)
                            break

                # Reverse dependencies take precedence
                rev_dep_val = self.config._eval_expr(self.rev_dep)

                if rev_dep_val != "n":
                    self.write_to_conf = True
                    new_val = self.config._eval_max(new_val, rev_dep_val)

            # Promote "m" to "y" for booleans
            if new_val == "m" and self.type == BOOL:
                new_val = "y"

        elif self.type == STRING:
            use_defaults = True

            if vis != "n":
                self.write_to_conf = True
                if self.user_val is not None:
                    new_val = self.user_val
                    use_defaults = False

            if use_defaults:
                for (val_expr, cond_expr) in self.def_exprs:
                    if self.config._eval_expr(cond_expr) != "n":
                        self.write_to_conf = True
                        new_val = self.config._get_str_value(val_expr)
                        break

        elif self.type == HEX or self.type == INT:
            has_active_range = False
            low = None
            high = None
            use_defaults = True

            base = 16 if self.type == HEX else 10

            for(l, h, cond_expr) in self.ranges:
                if self.config._eval_expr(cond_expr) != "n":
                    has_active_range = True

                    low_str = self.config._get_str_value(l)
                    high_str = self.config._get_str_value(h)

                    low = int(low_str, base) if \
                      _is_base_n(low_str, base) else 0
                    high = int(high_str, base) if \
                      _is_base_n(high_str, base) else 0

                    break

            if vis != "n":
                self.write_to_conf = True

                if self.user_val is not None and \
                   _is_base_n(self.user_val, base) and \
                   (not has_active_range or
                    low <= int(self.user_val, base) <= high):

                    # If the user value is OK, it is stored in exactly the same
                    # form as specified in the assignment (with or without
                    # "0x", etc).

                    use_defaults = False
                    new_val = self.user_val

            if use_defaults:
                for (val_expr, cond_expr) in self.def_exprs:
                    if self.config._eval_expr(cond_expr) != "n":
                        self.write_to_conf = True

                        # If the default value is OK, it is stored in exactly
                        # the same form as specified. Otherwise, it is clamped
                        # to the range, and the output has "0x" as appropriate
                        # for the type.

                        new_val = self.config._get_str_value(val_expr)

                        if _is_base_n(new_val, base):
                            new_val_num = int(new_val, base)
                            if has_active_range:
                                clamped_val = None

                                if new_val_num < low:
                                    clamped_val = low
                                elif new_val_num > high:
                                    clamped_val = high

                                if clamped_val is not None:
                                    new_val = (hex(clamped_val) if \
                                      self.type == HEX else str(clamped_val))

                            break
                else: # For the for loop
                    # If no user value or default kicks in but the hex/int has
                    # an active range, then the low end of the range is used,
                    # provided it's > 0, with "0x" prepended as appropriate.

                    if has_active_range and low > 0:
                        new_val = (hex(low) if self.type == HEX else str(low))

        self.cached_value = new_val
        return new_val

    def set_user_value(self, v):
        """Sets the user value of the symbol.

        Equal in effect to assigning the value to the symbol within a .config
        file. Use get_lower/upper_bound() or get_assignable_values() to find
        the range of currently assignable values for bool and tristate symbols;
        setting values outside this range will cause the user value to differ
        from the result of Symbol.get_value() (be truncated). Values that are
        invalid for the type (such as a_bool.set_user_value("foo")) are
        ignored, and a warning is emitted if an attempt is made to assign such
        a value.

        For any type of symbol, is_modifiable() can be used to check if a user
        value will currently have any effect on the symbol, as determined by
        its visibility and range of assignable values. Any value that is valid
        for the type (bool, tristate, etc.) will end up being reflected in
        get_user_value() though, and might have an effect later if conditions
        change. To get rid of the user value, use unset_user_value().

        Any symbols dependent on the symbol are (recursively) invalidated, so
        things will just work with regards to dependencies.

        v -- The user value to give to the symbol."""
        self._set_user_value_no_invalidate(v, False)

        # There might be something more efficient you could do here, but play
        # it safe.
        if self.name == "MODULES":
            self.config._invalidate_all()
            return

        self._invalidate()
        self._invalidate_dependent()

    def unset_user_value(self):
        """Resets the user value of the symbol, as if the symbol had never
        gotten a user value via Config.load_config() or
        Symbol.set_user_value()."""
        self._unset_user_value_no_recursive_invalidate()
        self._invalidate_dependent()

    def get_user_value(self):
        """Returns the value assigned to the symbol in a .config or via
        Symbol.set_user_value() (provided the value was valid for the type of the
        symbol). Returns None in case of no user value."""
        return self.user_val

    def get_name(self):
        """Returns the name of the symbol."""
        return self.name

    def get_prompts(self):
        """Returns a list of prompts defined for the symbol, in the order they
        appear in the configuration files. Returns the empty list for symbols
        with no prompt.

        This list will have a single entry for the vast majority of symbols
        having prompts, but having multiple prompts for a single symbol is
        possible through having multiple 'config' entries for it."""
        return [prompt for prompt, _ in self.orig_prompts]

    def get_upper_bound(self):
        """For string/hex/int symbols and for bool and tristate symbols that
        cannot be modified (see is_modifiable()), returns None.

        Otherwise, returns the highest value the symbol can be set to with
        Symbol.set_user_value() (that will not be truncated): one of "m" or "y",
        arranged from lowest to highest. This corresponds to the highest value
        the symbol could be given in e.g. the 'make menuconfig' interface.

        See also the tri_less*() and tri_greater*() functions, which could come
        in handy."""
        if self.type != BOOL and self.type != TRISTATE:
            return None
        rev_dep = self.config._eval_expr(self.rev_dep)
        # A bool selected to "m" gets promoted to "y"
        if self.type == BOOL and rev_dep == "m":
            rev_dep = "y"
        vis = self._get_visibility()
        if (tri_to_int[vis] - tri_to_int[rev_dep]) > 0:
            return vis
        return None

    def get_lower_bound(self):
        """For string/hex/int symbols and for bool and tristate symbols that
        cannot be modified (see is_modifiable()), returns None.

        Otherwise, returns the lowest value the symbol can be set to with
        Symbol.set_user_value() (that will not be truncated): one of "n" or "m",
        arranged from lowest to highest. This corresponds to the lowest value
        the symbol could be given in e.g. the 'make menuconfig' interface.

        See also the tri_less*() and tri_greater*() functions, which could come
        in handy."""
        if self.type != BOOL and self.type != TRISTATE:
            return None
        rev_dep = self.config._eval_expr(self.rev_dep)
        # A bool selected to "m" gets promoted to "y"
        if self.type == BOOL and rev_dep == "m":
            rev_dep = "y"
        if (tri_to_int[self._get_visibility()] - tri_to_int[rev_dep]) > 0:
            return rev_dep
        return None

    def get_assignable_values(self):
        """For string/hex/int symbols and for bool and tristate symbols that
        cannot be modified (see is_modifiable()), returns the empty list.

        Otherwise, returns a list containing the user values that can be
        assigned to the symbol (that won't be truncated). Usage example:

        if "m" in sym.get_assignable_values():
            sym.set_user_value("m")

        This is basically a more convenient interface to
        get_lower/upper_bound() when wanting to test if a particular tristate
        value can be assigned."""
        if self.type != BOOL and self.type != TRISTATE:
            return []
        rev_dep = self.config._eval_expr(self.rev_dep)
        # A bool selected to "m" gets promoted to "y"
        if self.type == BOOL and rev_dep == "m":
            rev_dep = "y"
        res = ["n", "m", "y"][tri_to_int[rev_dep] :
                              tri_to_int[self._get_visibility()] + 1]
        return res if len(res) > 1 else []

    def get_type(self):
        """Returns the type of the symbol: one of UNKNOWN, BOOL, TRISTATE,
        STRING, HEX, or INT. These are defined at the top level of the module,
        so you'd do something like

        if sym.get_type() == kconfiglib.STRING:
            ..."""
        return self.type

    def get_visibility(self):
        """Returns the visibility of the symbol: one of "n", "m" or "y". For
        bool and tristate symbols, this is an upper bound on the value users
        can set for the symbol. For other types of symbols, a visibility of "n"
        means the user value will be ignored. A visibility of "n" corresponds
        to not being visible in the 'make *config' interfaces.

        Example (assuming we're running with modules enabled -- i.e., MODULES
        set to 'y'):

        # Assume this has been assigned 'n'
        config N_SYM
            tristate "N_SYM"

        # Assume this has been assigned 'm'
        config M_SYM
            tristate "M_SYM"

        # Has visibility 'n'
        config A
            tristate "A"
            depends on N_SYM

        # Has visibility 'm'
        config B
            tristate "B"
            depends on M_SYM

        # Has visibility 'y'
        config C
            tristate "C"

        # Has no prompt, and hence visibility 'n'
        config D
            tristate

        Having visibility be tri-valued ensures that e.g. a symbol cannot be
        set to "y" by the user if it depends on a symbol with value "m", which
        wouldn't be safe.

        You should probably look at get_lower/upper_bound(),
        get_assignable_values() and is_modifiable() before using this."""
        return self._get_visibility()

    def get_parent(self):
        """Returns the menu or choice statement that contains the symbol, or
        None if the symbol is at the top level. Note that if statements are
        treated as syntactic and do not have an explicit class
        representation."""
        return self.parent

    def get_referenced_symbols(self, refs_from_enclosing = False):
        """Returns the set() of all symbols referenced by this symbol. For
        example, the symbol defined by

        config FOO
            bool
            prompt "foo" if A && B
            default C if D
            depends on E
            select F if G

        references the symbols A through G.

        refs_from_enclosing (default: False) -- If True, the symbols
                            referenced by enclosing menus and if's will be
                            included in the result."""
        return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms

    def get_selected_symbols(self):
        """Returns the set() of all symbols X for which this symbol has a
        'select X' or 'select X if Y' (regardless of whether Y is satisfied or
        not). This is a subset of the symbols returned by
        get_referenced_symbols()."""
        return self.selected_syms

    def get_help(self):
        """Returns the help text of the symbol, or None if the symbol has no
        help text."""
        return self.help

    def get_config(self):
        """Returns the Config instance this symbol is from."""
        return self.config

    def get_def_locations(self):
        """Returns a list of (filename, linenr) tuples, where filename (string)
        and linenr (int) represent a location where the symbol is defined. For
        the vast majority of symbols this list will only contain one element.
        For the following Kconfig, FOO would get two entries: the lines marked
        with *.

        config FOO *
            bool "foo prompt 1"

        config FOO *
            bool "foo prompt 2"
        """
        return self.def_locations

    def get_ref_locations(self):
        """Returns a list of (filename, linenr) tuples, where filename (string)
        and linenr (int) represent a location where the symbol is referenced in
        the configuration. For example, the lines marked by * would be included
        for FOO below:

        config A
            bool
            default BAR || FOO *

        config B
            tristate
            depends on FOO *
            default m if FOO *

        if FOO *
            config A
                bool "A"
        endif

        config FOO (definition not included)
            bool
        """
        return self.ref_locations

    def is_modifiable(self):
        """Returns True if the value of the symbol could be modified by calling
        Symbol.set_user_value() and False otherwise.

        For bools and tristates, this corresponds to the symbol being visible
        in the 'make menuconfig' interface and not already being pinned to a
        specific value (e.g. because it is selected by another symbol).

        For strings and numbers, this corresponds to just being visible. (See
        Symbol.get_visibility().)"""
        if self.is_special_:
            return False
        if self.type == BOOL or self.type == TRISTATE:
            rev_dep = self.config._eval_expr(self.rev_dep)
            # A bool selected to "m" gets promoted to "y"
            if self.type == BOOL and rev_dep == "m":
                rev_dep = "y"
            return (tri_to_int[self._get_visibility()] -
                    tri_to_int[rev_dep]) > 0
        return self._get_visibility() != "n"

    def is_defined(self):
        """Returns False if the symbol is referred to in the Kconfig but never
        actually defined, otherwise True."""
        return self.is_defined_

    def is_special(self):
        """Returns True if the symbol is one of the special symbols n, m, y, or
        UNAME_RELEASE, or gets its value from the environment. Otherwise,
        returns False."""
        return self.is_special_

    def is_from_environment(self):
        """Returns True if the symbol gets its value from the environment.
        Otherwise, returns False."""
        return self.is_from_env

    def has_ranges(self):
        """Returns True if the symbol is of type INT or HEX and has ranges that
        limits what values it can take on, otherwise False."""
        return self.ranges != []

    def is_choice_symbol(self):
        """Returns True if the symbol is in a choice statement and is an actual
        choice symbol (see Choice.get_symbols()); otherwise, returns
        False."""
        return self.is_choice_symbol_

    def is_choice_selection(self):
        """Returns True if the symbol is contained in a choice statement and is
        the selected item, otherwise False. Equivalent to 'sym.is_choice_symbol()
        and sym.get_parent().get_selection() is sym'."""
        return self.is_choice_symbol_ and self.parent.get_selection() is self

    def __str__(self):
        """Returns a string containing various information about the symbol."""
        return self.config._get_sym_or_choice_str(self)

    #
    # Private methods
    #

    def __init__(self):
        """Symbol constructor -- not intended to be called directly by
        kconfiglib clients."""

        # Set default values
        _HasVisibility.__init__(self)

        self.config = None

        self.parent = None
        self.name = None
        self.type = UNKNOWN

        self.def_exprs = []
        self.ranges = []
        self.rev_dep = "n"

        # The prompt, default value and select conditions without any
        # dependencies from menus or if's propagated to them

        self.orig_prompts = []
        self.orig_def_exprs = []
        self.orig_selects = []

        # Dependencies inherited from containing menus and if's
        self.deps_from_containing = None

        self.help = None

        # The set of symbols referenced by this symbol (see
        # get_referenced_symbols())
        self.referenced_syms = set()

        # The set of symbols selected by this symbol (see
        # get_selected_symbols())
        self.selected_syms = set()

        # Like 'referenced_syms', but includes symbols from
        # dependencies inherited from enclosing menus and if's
        self.all_referenced_syms = set()

        # This is set to True for "actual" choice symbols. See
        # Choice._determine_actual_symbols(). The trailing underscore avoids a
        # collision with is_choice_symbol().
        self.is_choice_symbol_ = False

        # This records only dependencies specified with 'depends on'. Needed
        # when determining actual choice items (hrrrr...). See also
        # Choice._determine_actual_symbols().
        self.menu_dep = None

        # See Symbol.get_ref/def_locations().
        self.def_locations = []
        self.ref_locations = []

        self.user_val = None

        # Flags

        # Should the symbol get an entry in .config?
        self.write_to_conf = False

        # Caches the calculated value
        self.cached_value = None

        # Note: An instance variable 'self.dep' gets set on the Symbol in
        # Config._build_dep(), linking the symbol to the symbols that
        # immediately depend on it (in a caching/invalidation sense). The total
        # set of dependent symbols for the symbol (the transitive closure) is
        # calculated on an as-needed basis in _get_dependent().

        # Caches the total list of dependent symbols. Calculated in
        # _get_dependent().
        self.cached_deps = None

        # Does the symbol have an entry in the Kconfig file? The trailing
        # underscore avoids a collision with is_defined().
        self.is_defined_ = False

        # Does the symbol get its value in some special way, e.g. from the
        # environment or by being one of the special symbols n, m, and y? If
        # so, the value is stored in self.cached_value, which is never
        # invalidated. The trailing underscore avoids a collision with
        # is_special().
        self.is_special_ = False

        # Does the symbol get its value from the environment?
        self.is_from_env = False

    def _invalidate(self):
        if self.is_special_:
            return

        if self.is_choice_symbol_:
            self.parent._invalidate()

        _HasVisibility._invalidate(self)

        self.write_to_conf = False
        self.cached_value = None

    def _invalidate_dependent(self):
        for sym in self._get_dependent():
            sym._invalidate()

    def _set_user_value_no_invalidate(self, v, suppress_load_warnings):
        """Like set_user_value(), but does not invalidate any symbols.

        suppress_load_warnings --
          some warnings are annoying when loading a .config that can be helpful
          when manually invoking set_user_value(). This flag is set to True to
          suppress such warnings.

          Perhaps this could be made optional for load_config() instead."""

        if self.is_special_:
            if self.is_from_env:
                self.config._warn('attempt to assign the value "{0}" to the '
                                  'symbol {1}, which gets its value from the '
                                  'environment. Assignment ignored.'
                                  .format(v, self.name))
            else:
                self.config._warn('attempt to assign the value "{0}" to the '
                                  'special symbol {1}. Assignment ignored.'
                                  .format(v, self.name))

            return


        if not self.is_defined_:
            filename, linenr = self.ref_locations[0]

            self.config._undef_assign('attempt to assign the value "{0}" to {1}, '
                                      "which is referenced at {2}:{3} but never "
                                      "defined. Assignment ignored."
                                      .format(v, self.name, filename, linenr))
            return

        # Check if the value is valid for our type

        if not (( self.type == BOOL     and (v == "n" or v == "y")    ) or
                ( self.type == TRISTATE and (v == "n" or v == "m" or
                                             v == "y")                ) or
                ( self.type == STRING                                 ) or
                ( self.type == INT      and _is_base_n(v, 10)         ) or
                ( self.type == HEX      and _is_base_n(v, 16)         )):

            self.config._warn('the value "{0}" is invalid for {1}, which has type {2}. '
                              "Assignment ignored."
                              .format(v, self.name, typename[self.type]))
            return

        if self.prompts == [] and not suppress_load_warnings:
            self.config._warn('assigning "{0}" to the symbol {1} which '
                              'lacks prompts and thus has visibility "n". '
                              'The assignment will have no effect.'
                              .format(v, self.name))

        self.user_val = v

        if self.is_choice_symbol_ and (self.type == BOOL or
                                       self.type == TRISTATE):
            choice = self.parent
            if v == "y":
                choice.user_val = self
                choice.user_mode = "y"
            elif v == "m":
                choice.user_val = None
                choice.user_mode = "m"

    def _unset_user_value_no_recursive_invalidate(self):
        self._invalidate()
        self.user_val = None

        if self.is_choice_symbol_:
            self.parent._unset_user_value()

    def _make_conf(self):
        if self.already_written:
            return []

        self.already_written = True

        # Note: write_to_conf is determined in get_value()
        val = self.get_value()
        if not self.write_to_conf:
            return []

        if self.type == BOOL or self.type == TRISTATE:
            if val == "m" or val == "y":
                return ["CONFIG_{0}={1}".format(self.name, val)]
            return ["# CONFIG_{0} is not set".format(self.name)]

        elif self.type == STRING:
            # Escape \ and "
            return ['CONFIG_{0}="{1}"'
                    .format(self.name,
                            val.replace("\\", "\\\\").replace('"', '\\"'))]

        elif self.type == INT or self.type == HEX:
            return ["CONFIG_{0}={1}".format(self.name, val)]

        else:
            _internal_error('Internal error while creating .config: unknown type "{0}".'
                            .format(self.type))

    def _get_dependent(self):
        """Returns the set of symbols that should be invalidated if the value
        of the symbol changes, because they might be affected by the change.
        Note that this is an internal API -- it's probably of limited
        usefulness to clients."""
        if self.cached_deps is not None:
            return self.cached_deps

        res = set()

        self._add_dependent_ignore_siblings(res)
        if self.is_choice_symbol_:
            for s in self.parent.get_symbols():
                if s is not self:
                    res.add(s)
                    s._add_dependent_ignore_siblings(res)

        self.cached_deps = res
        return res

    def _add_dependent_ignore_siblings(self, to):
        """Calculating dependencies gets a bit tricky for choice items as they
        all depend on each other, potentially leading to infinite recursion.
        This helper function calculates dependencies ignoring the other symbols
        in the choice. It also works fine for symbols that are not choice
        items."""
        for s in self.dep:
            to.add(s)
            to |= s._get_dependent()

    def _has_auto_menu_dep_on(self, on):
        """See Choice._determine_actual_symbols()."""
        if not isinstance(self.parent, Choice):
            _internal_error("Attempt to determine auto menu dependency for symbol ouside of choice.")

        if self.prompts == []:
            # If we have no prompt, use the menu dependencies instead (what was
            # specified with 'depends on')
            return self.menu_dep is not None and \
                   self.config._expr_depends_on(self.menu_dep, on)

        for (_, cond_expr) in self.prompts:
            if self.config._expr_depends_on(cond_expr, on):
                return True

        return False

class Menu(Item):

    """Represents a menu statement."""

    #
    # Public interface
    #

    def get_config(self):
        """Return the Config instance this menu is from."""
        return self.config

    def get_visibility(self):
        """Returns the visibility of the menu. This also affects the visibility
        of subitems. See also Symbol.get_visibility()."""
        return self.config._eval_expr(self.dep_expr)

    def get_visible_if_visibility(self):
        """Returns the visibility the menu gets from its 'visible if'
        condition. "y" if the menu has no 'visible if' condition."""
        return self.config._eval_expr(self.visible_if_expr)

    def get_items(self, recursive = False):
        """Returns a list containing the items (symbols, menus, choice
        statements and comments) in in the menu, in the same order that the
        items appear within the menu.

        recursive (default: False) -- True if items contained in items within
                                      the menu should be included
                                      recursively (preorder)."""

        if not recursive:
            return self.block.get_items()

        res = []
        for item in self.block.get_items():
            res.append(item)
            if isinstance(item, Menu):
                res.extend(item.get_items(True))
            elif isinstance(item, Choice):
                res.extend(item.get_items())
        return res

    def get_symbols(self, recursive = False):
        """Returns a list containing the symbols in the menu, in the same order
        that they appear within the menu.

        recursive (default: False) -- True if symbols contained in items within
                                      the menu should be included
                                      recursively."""

        return [item for item in self.get_items(recursive) if isinstance(item, Symbol)]

    def get_title(self):
        """Returns the title text of the menu."""
        return self.title

    def get_parent(self):
        """Returns the menu or choice statement that contains the menu, or
        None if the menu is at the top level. Note that if statements are
        treated as syntactic sugar and do not have an explicit class
        representation."""
        return self.parent

    def get_referenced_symbols(self, refs_from_enclosing = False):
        """See Symbol.get_referenced_symbols()."""
        return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms

    def get_location(self):
        """Returns the location of the menu as a (filename, linenr) tuple,
        where filename is a string and linenr an int."""
        return (self.filename, self.linenr)

    def __str__(self):
        """Returns a string containing various information about the menu."""
        depends_on_str = self.config._expr_val_str(self.orig_deps,
                                                   "(no dependencies)")
        visible_if_str = self.config._expr_val_str(self.visible_if_expr,
                                                   "(no dependencies)")

        additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
                                                              "(no additional dependencies)")

        return _sep_lines("Menu",
                          "Title                     : " + self.title,
                          "'depends on' dependencies : " + depends_on_str,
                          "'visible if' dependencies : " + visible_if_str,
                          "Additional dependencies from enclosing menus and if's:",
                          additional_deps_str,
                          "Location: {0}:{1}".format(self.filename, self.linenr))

    #
    # Private methods
    #

    def __init__(self):
        """Menu constructor -- not intended to be called directly by
        kconfiglib clients."""

        self.config = None

        self.parent = None
        self.title = None
        self.block = None
        self.dep_expr = None

        # Dependency expression without dependencies from enclosing menus and
        # if's propagated
        self.orig_deps = None

        # Dependencies inherited from containing menus and if's
        self.deps_from_containing = None

        # The 'visible if' expression
        self.visible_if_expr = None

        # The set of symbols referenced by this menu (see
        # get_referenced_symbols())
        self.referenced_syms = set()

        # Like 'referenced_syms', but includes symbols from
        # dependencies inherited from enclosing menus and if's
        self.all_referenced_syms = None

        self.filename = None
        self.linenr = None

    def _make_conf(self):
        item_conf = self.block._make_conf()

        if self.config._eval_expr(self.dep_expr) != "n" and \
           self.config._eval_expr(self.visible_if_expr) != "n":
            return ["\n#\n# {0}\n#".format(self.title)] + item_conf
        return item_conf

class Choice(Item, _HasVisibility):

    """Represents a choice statement. A choice can be in one of three modes:

    "n" - The choice is not visible and no symbols can be selected.

    "m" - Any number of symbols can be set to "m". The rest will be "n". This
          is safe since potentially conflicting options don't actually get
          compiled into the kernel simultaneously with "m".

    "y" - One symbol will be "y" while the rest are "n".

    Only tristate choices can be in "m" mode, and the visibility of the choice
    is an upper bound on the mode, so that e.g. a choice that depends on a
    symbol with value "m" will be in "m" mode.

    The mode changes automatically when a value is assigned to a symbol within
    the choice.

    See Symbol.get_visibility() too."""

    #
    # Public interface
    #

    def get_selection(self):
        """Returns the symbol selected (either by the user or through
        defaults), or None if either no symbol is selected or the mode is not
        "y"."""
        if self.cached_selection is not None:
            if self.cached_selection == NO_SELECTION:
                return None
            return self.cached_selection

        if self.get_mode() != "y":
            return self._cache_ret(None)

        # User choice available?
        if self.user_val is not None and \
           self.user_val._get_visibility() == "y":
            return self._cache_ret(self.user_val)

        if self.optional:
            return self._cache_ret(None)

        return self._cache_ret(self.get_selection_from_defaults())

    def get_selection_from_defaults(self):
        """Like Choice.get_selection(), but acts as if no symbol has been
        selected by the user and no 'optional' flag is in effect."""

        if self.actual_symbols == []:
            return None

        for (symbol, cond_expr) in self.def_exprs:
            if self.config._eval_expr(cond_expr) != "n":
                chosen_symbol = symbol
                break
        else:
            chosen_symbol = self.actual_symbols[0]

        # Is the chosen symbol visible?
        if chosen_symbol._get_visibility() != "n":
            return chosen_symbol
        # Otherwise, pick the first visible symbol
        for sym in self.actual_symbols:
            if sym._get_visibility() != "n":
                return sym
        return None

    def get_user_selection(self):
        """If the choice is in "y" mode and has a user-selected symbol, returns
        that symbol. Otherwise, returns None."""
        return self.user_val

    def get_config(self):
        """Returns the Config instance this choice is from."""
        return self.config

    def get_name(self):
        """For named choices, returns the name. Returns None for unnamed
        choices. No named choices appear anywhere in the kernel Kconfig files
        as of Linux 3.7.0-rc8."""
        return self.name

    def get_prompts(self):
        """Returns a list of prompts defined for the choice, in the order they
        appear in the configuration files. Returns the empty list for choices
        with no prompt.

        This list will have a single entry for the vast majority of choices
        having prompts, but having multiple prompts for a single choice is
        possible through having multiple 'choice' entries for it (though I'm
        not sure if that ever happens in practice)."""
        return [prompt for prompt, _ in self.orig_prompts]

    def get_help(self):
        """Returns the help text of the choice, or None if the choice has no
        help text."""
        return self.help

    def get_type(self):
        """Returns the type of the choice. See Symbol.get_type()."""
        return self.type

    def get_items(self):
        """Gets all items contained in the choice in the same order as within
        the configuration ("items" instead of "symbols" since choices and
        comments might appear within choices. This only happens in one place as
        of Linux 3.7.0-rc8, in drivers/usb/gadget/Kconfig)."""
        return self.block.get_items()

    def get_symbols(self):
        """Returns a list containing the choice's symbols.

        A quirk (perhaps a bug) of Kconfig is that you can put items within a
        choice that will not be considered members of the choice insofar as
        selection is concerned. This happens for example if one symbol within a
        choice 'depends on' the symbol preceding it, or if you put non-symbol
        items within choices.

        As of Linux 3.7.0-rc8, this seems to be used intentionally in one
        place: drivers/usb/gadget/Kconfig.

        This function returns the "proper" symbols of the choice in the order
        they appear in the choice, excluding such items. If you want all items
        in the choice, use get_items()."""
        return self.actual_symbols

    def get_parent(self):
        """Returns the menu or choice statement that contains the choice, or
        None if the choice is at the top level. Note that if statements are
        treated as syntactic sugar and do not have an explicit class
        representation."""
        return self.parent

    def get_referenced_symbols(self, refs_from_enclosing = False):
        """See Symbol.get_referenced_symbols()."""
        return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms

    def get_def_locations(self):
        """Returns a list of (filename, linenr) tuples, where filename (string)
        and linenr (int) represent a location where the choice is defined. For
        the vast majority of choices (all of them as of Linux 3.7.0-rc8) this
        list will only contain one element, but its possible for named choices
        to be defined in multiple locations."""
        return self.def_locations

    def get_visibility(self):
        """Returns the visibility of the choice statement: one of "n", "m" or
        "y". This acts as an upper limit on the mode of the choice (though bool
        choices can only have the mode "y"). See the class documentation for an
        explanation of modes."""
        return self._get_visibility()

    def get_mode(self):
        """Returns the mode of the choice. See the class documentation for
        an explanation of modes."""
        minimum_mode = "n" if self.optional else "m"
        mode = self.user_mode if self.user_mode is not None else minimum_mode
        mode = self.config._eval_min(mode, self._get_visibility())

        # Promote "m" to "y" for boolean choices
        if mode == "m" and self.type == BOOL:
            return "y"

        return mode

    def is_optional(self):
        """Returns True if the symbol has the optional flag set (and so will default
        to "n" mode). Otherwise, returns False."""
        return self.optional

    def __str__(self):
        """Returns a string containing various information about the choice
        statement."""
        return self.config._get_sym_or_choice_str(self)

    #
    # Private methods
    #

    def __init__(self):
        """Choice constructor -- not intended to be called directly by
        kconfiglib clients."""

        _HasVisibility.__init__(self)

        self.config = None

        self.parent = None
        self.name = None # Yes, choices can be named
        self.type = UNKNOWN
        self.def_exprs = []
        self.help = None
        self.optional = False
        self.block = None

        # The prompts and default values without any dependencies from
        # enclosing menus or if's propagated

        self.orig_prompts = []
        self.orig_def_exprs = []

        # Dependencies inherited from containing menus and if's
        self.deps_from_containing = None

        # We need to filter out symbols that appear within the choice block but
        # are not considered choice items (see
        # Choice._determine_actual_symbols()) This list holds the "actual" choice
        # items.
        self.actual_symbols = []

        # The set of symbols referenced by this choice (see
        # get_referenced_symbols())
        self.referenced_syms = set()

        # Like 'referenced_syms', but includes symbols from
        # dependencies inherited from enclosing menus and if's
        self.all_referenced_syms = set()

        # See Choice.get_def_locations()
        self.def_locations = []

        self.user_val = None
        self.user_mode = None

        self.cached_selection = None

    def _determine_actual_symbols(self):
        """If a symbol's visibility depends on the preceding symbol within a
        choice, it is no longer viewed as a choice item (quite possibly a bug,
        but some things consciously use it.. ugh. It stems from automatic
        submenu creation). In addition, it's possible to have choices and
        comments within choices, and those shouldn't be considered as choice
        items either. Only drivers/usb/gadget/Kconfig seems to depend on any of
        this. This method computes the "actual" items in the choice and sets
        the is_choice_symbol_ flag on them (retrieved via is_choice_symbol()).

        Don't let this scare you: an earlier version simply checked for a
        sequence of symbols where all symbols after the first appeared in the
        'depends on' expression of the first, and that worked fine.  The added
        complexity is to be future-proof in the event that
        drivers/usb/gadget/Kconfig turns even more sinister. It might very well
        be overkilling things (especially if that file is refactored ;)."""

        items = self.block.get_items()

        # Items might depend on each other in a tree structure, so we need a
        # stack to keep track of the current tentative parent
        stack = []

        for item in items:
            if not isinstance(item, Symbol):
                stack = []
                continue

            while stack != []:
                if item._has_auto_menu_dep_on(stack[-1]):
                    # The item should not be viewed as a choice item, so don't
                    # set item.is_choice_symbol_.
                    stack.append(item)
                    break
                else:
                    stack.pop()
            else:
                item.is_choice_symbol_ = True
                self.actual_symbols.append(item)
                stack.append(item)

    def _cache_ret(self, selection):
        # As None is used to indicate the lack of a cached value we can't use
        # that to cache the fact that the choice has no selection. Instead, we
        # use the symbolic constant NO_SELECTION.
        if selection is None:
            self.cached_selection = NO_SELECTION
        else:
            self.cached_selection = selection

        return selection

    def _invalidate(self):
        _HasVisibility._invalidate(self)
        self.cached_selection = None

    def _unset_user_value(self):
        self._invalidate()
        self.user_val = None
        self.user_mode = None

    def _make_conf(self):
        return self.block._make_conf()

class Comment(Item):

    """Represents a comment statement."""

    #
    # Public interface
    #

    def get_config(self):
        """Returns the Config instance this comment is from."""
        return self.config

    def get_visibility(self):
        """Returns the visibility of the comment. See also
        Symbol.get_visibility()."""
        return self.config._eval_expr(self.dep_expr)

    def get_text(self):
        """Returns the text of the comment."""
        return self.text

    def get_parent(self):
        """Returns the menu or choice statement that contains the comment, or
        None if the comment is at the top level. Note that if statements are
        treated as syntactic sugar and do not have an explicit class
        representation."""
        return self.parent

    def get_referenced_symbols(self, refs_from_enclosing = False):
        """See Symbol.get_referenced_symbols()."""
        return self.all_referenced_syms if refs_from_enclosing else self.referenced_syms

    def get_location(self):
        """Returns the location of the comment as a (filename, linenr) tuple,
        where filename is a string and linenr an int."""
        return (self.filename, self.linenr)

    def __str__(self):
        """Returns a string containing various information about the comment."""
        dep_str = self.config._expr_val_str(self.orig_deps, "(no dependencies)")

        additional_deps_str = " " + self.config._expr_val_str(self.deps_from_containing,
                                                              "(no additional dependencies)")

        return _sep_lines("Comment",
                          "Text: "         + str(self.text),
                          "Dependencies: " + dep_str,
                          "Additional dependencies from enclosing menus and if's:",
                          additional_deps_str,
                          "Location: {0}:{1}".format(self.filename, self.linenr))

    #
    # Private methods
    #

    def __init__(self):
        """Comment constructor -- not intended to be called directly by
        kconfiglib clients."""

        self.config = None

        self.parent = None
        self.text = None
        self.dep_expr = None

        # Dependency expression without dependencies from enclosing menus and
        # if's propagated
        self.orig_deps = None

        # Dependencies inherited from containing menus and if's
        self.deps_from_containing = None

        # The set of symbols referenced by this comment (see
        # get_referenced_symbols())
        self.referenced_syms = set()

        # Like 'referenced_syms', but includes symbols from
        # dependencies inherited from enclosing menus and if's
        self.all_referenced_syms = None

        self.filename = None
        self.linenr = None

    def _make_conf(self):
        if self.config._eval_expr(self.dep_expr) != "n":
            return ["\n#\n# {0}\n#".format(self.text)]
        return []

class _Feed:

    """Class for working with sequences in a stream-like fashion; handy for tokens."""

    def __init__(self, items):
        self.items = items
        self.length = len(self.items)
        self.i = 0

    def get_next(self):
        if self.i >= self.length:
            return None

        item = self.items[self.i]
        self.i += 1
        return item

    def peek_next(self):
        return None if self.i >= self.length else self.items[self.i]

    def go_to_start(self):
        self.i = 0

    def __getitem__(self, index):
        return self.items[index]

    def __len__(self):
        return len(self.items)

    def is_empty(self):
        return self.items == []

    def check(self, token):
        """Check if the next token is 'token'. If so, remove it from the token
        feed and return True. Otherwise, leave it in and return False."""
        if self.i >= self.length:
            return None

        if self.items[self.i] == token:
            self.i += 1
            return True

        return False

    def remove_while(self, pred):
        while self.i < self.length and pred(self.items[self.i]):
            self.i += 1

    def go_back(self):
        if self.i <= 0:
            _internal_error("Attempt to move back in Feed while already at the beginning.")
        self.i -= 1

class _FileFeed(_Feed):

    """Feed subclass that keeps track of the current filename and line
    number."""

    def __init__(self, lines, filename):
        self.filename = _clean_up_path(filename)
        _Feed.__init__(self, lines)

    def get_filename(self):
        return self.filename

    def get_linenr(self):
        return self.i

#
# Misc. public global utility functions
#

def tri_less(v1, v2):
    """Returns True if the tristate v1 is less than the tristate v2, where "n",
    "m" and "y" are ordered from lowest to highest. Otherwise, returns
    False."""
    return tri_to_int[v1] < tri_to_int[v2]

def tri_less_eq(v1, v2):
    """Returns True if the tristate v1 is less than or equal to the tristate
    v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
    returns False."""
    return tri_to_int[v1] <= tri_to_int[v2]

def tri_greater(v1, v2):
    """Returns True if the tristate v1 is greater than the tristate v2, where
    "n", "m" and "y" are ordered from lowest to highest. Otherwise, returns
    False."""
    return tri_to_int[v1] > tri_to_int[v2]

def tri_greater_eq(v1, v2):
    """Returns True if the tristate v1 is greater than or equal to the tristate
    v2, where "n", "m" and "y" are ordered from lowest to highest. Otherwise,
    returns False."""
    return tri_to_int[v1] >= tri_to_int[v2]

#
# Helper functions, mostly related to text processing
#

def _strip_quotes(s, line, filename, linenr):
    """Removes any quotes surrounding 's' if it has them; otherwise returns 's'
    unmodified."""
    s = s.strip()
    if not s:
        return ""
    if s[0] == '"' or s[0] == "'":
        if len(s) < 2 or s[-1] != s[0]:
            _parse_error(line,
                         "malformed string literal",
                         filename,
                         linenr)
        return s[1:-1]
    return s

def _indentation(line):
    """Returns the indentation of the line, treating tab stops as being spaced
    8 characters apart."""
    if line.isspace():
        _internal_error("Attempt to take indentation of blank line.")
    indent = 0
    for c in line:
        if c == " ":
            indent += 1
        elif c == "\t":
            # Go to the next tab stop
            indent = (indent + 8) & ~7
        else:
            return indent

def _deindent(line, indent):
    """Deindent 'line' by 'indent' spaces."""
    line = line.expandtabs()
    if len(line) <= indent:
        return line
    return line[indent:]

def _is_base_n(s, n):
    try:
        int(s, n)
        return True
    except ValueError:
        return False

def _sep_lines(*args):
    """Returns a string comprised of all arguments, with newlines inserted
    between them."""
    return "\n".join(args)

def _comment(s):
    """Returns a new string with "#" inserted before each line in 's'."""
    if not s:
        return "#"
    res = "".join(["#" + line for line in s.splitlines(True)])
    if s.endswith("\n"):
        return res + "#"
    return res

def _get_lines(filename):
    """Returns a list of lines from 'filename', joining any line ending in \\
    with the following line."""
    with open(filename, "r") as f:
        lines = []
        accum = ""
        while 1:
            line = f.readline()

            if line == "":
                return lines

            if line.endswith("\\\n"):
                accum += line[:-2]
            else:
                accum += line
                lines.append(accum)
                accum = ""

def _strip_trailing_slash(path):
    """Removes any trailing slash from 'path'."""
    return path[:-1] if path.endswith("/") else path

def _clean_up_path(path):
    """Strips any initial "./" and trailing slash from 'path'."""
    if path.startswith("./"):
        path = path[2:]
    return _strip_trailing_slash(path)

#
# Error handling
#

class Kconfig_Syntax_Error(Exception):
    """Exception raised for syntax errors."""
    pass

class Internal_Error(Exception):
    """Exception raised for internal errors."""
    pass

def _tokenization_error(s, index, filename, linenr):
    if filename is not None:
        assert linenr is not None
        sys.stderr.write("{0}:{1}:\n".format(filename, linenr))

    if s.endswith("\n"):
        s = s[:-1]

    # Calculate the visual offset corresponding to index 'index' in 's'
    # assuming tabstops are spaced 8 characters apart
    vis_index = 0
    for c in s[:index]:
        if c == "\t":
            vis_index = (vis_index + 8) & ~7
        else:
            vis_index += 1

    # Don't output actual tabs to be independent of how the terminal renders
    # them
    s = s.expandtabs()

    raise Kconfig_Syntax_Error, (
        _sep_lines("Error during tokenization at location indicated by caret.\n",
                   s,
                   " " * vis_index + "^\n"))

def _parse_error(s, msg, filename, linenr):
    error_str = ""

    if filename is not None:
        assert linenr is not None
        error_str += "{0}:{1}: ".format(filename, linenr)

    if s.endswith("\n"):
        s = s[:-1]

    error_str += 'Error while parsing "{0}"'.format(s) + \
      ("." if msg is None else ": " + msg)

    raise Kconfig_Syntax_Error, error_str

def _internal_error(msg):
    msg += "\nSorry! You may want to send an email to kconfiglib@gmail.com " \
           "to tell me about this. Include the message above and the stack " \
           "trace and describe what you were doing."

    raise Internal_Error, msg

if use_psyco:
    import psyco

    Config._tokenize  = psyco.proxy(Config._tokenize)
    Config._eval_expr = psyco.proxy(Config._eval_expr)

    _indentation = psyco.proxy(_indentation)
    _get_lines   = psyco.proxy(_get_lines)
