#
# SPDX-License-Identifier:	GPL-2.0+
#
# 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)
