# 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 [ARCH=<arch>] SCRIPT=<path to script> [SCRIPT_ARG=<arg>]

Using the 'scriptconfig' target ensures that required environment variables
(SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly.

Scripts receive the name of the Kconfig file to load in sys.argv[1]. As of
Linux 4.1.0-rc5, this is always "Kconfig" from the kernel top-level directory.
If an argument is provided with SCRIPT_ARG, it appears as sys.argv[2].

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

 $ make iscriptconfig [ARCH=<arch>]

Kconfiglib supports both Python 2 and Python 3. For (i)scriptconfig, the Python
interpreter to use can be passed in PYTHONCMD, which defaults to 'python'. PyPy
works well too, and might give a nice speedup for long-running jobs.

The examples/ directory contains short example scripts, 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

testsuite.py contains the test suite. See the top of the script for how to run
it.

Credits: Written by Ulf "Ulfalizer" Magnusson

Send bug reports, suggestions and other feedback to ulfalizer a.t Google's
email service. 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."""

import os
import re
import sys
import glob

# File layout:
#
# Public classes
# Public functions
# Internal classes
# Internal functions
# Internal global constants

# Line length: 79 columns

#
# Public classes
#

class Config(object):

    """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=None, 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, you'll probably want "Kconfig"
           from the top-level directory, as environment variables will make
           sure the right Kconfig is included from there
           (arch/<architecture>/Kconfig). If you are using Kconfiglib via 'make
           scriptconfig', the filename of the base base Kconfig file will be in
           sys.argv[1].

        base_dir (default: None): 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 existing environment variables will be expanded.

           If None (the default), the environment variable 'srctree' will be
           used if set, and the current directory otherwise. 'srctree' is set
           by the Linux makefiles to the top-level kernel directory. A default
           of "." would not work with an alternative build directory.

        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 = {}
        # Python 2/3 compatibility hack. This is the only one needed.
        if sys.version_info[0] >= 3:
            self.syms_iter = self.syms.values
        else:
            self.syms_iter = self.syms.itervalues

        # 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 = {}

        # Lists containing all choices, menus and comments in the configuration
        self.choices = []
        self.menus = []
        self.comments = []

        def register_special_symbol(type_, name, val):
            sym = Symbol()
            sym.is_special_ = True
            sym.is_defined_ = True
            sym.config = self
            sym.name = name
            sym.type = type_
            sym.cached_val = val
            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
        if base_dir is None:
            self.base_dir = self.srctree
        else:
            self.base_dir = 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

        # 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._cur_item = None
        self._line = None
        self._filename = None
        self._linenr = None
        self._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 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 particular arch/ subdirectory
        containing architecture-specific 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_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 get_kconfig_filename(self):
        """Returns the name of the (base) kconfig file this configuration was
        loaded from."""
        return self.filename

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

    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 consists of 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_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__().

        WARNING: A wart here is that scripts/kconfig/Makefile sometimes uses
        the --defconfig=<defconfig> option when calling the C implementation of
        e.g. 'make defconfig'. This option overrides the 'option
        defconfig_list' symbol, meaning the result from
        get_defconfig_filename() might not match what 'make defconfig' would
        use. That probably ought to be worked around somehow, so that this
        function always gives the "expected" result."""
        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 __getitem__(self, name):
        """Returns the symbol with name 'name'. Raises KeyError if the symbol
        does not appear in the configuration."""
        return self.syms[name]

    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 list(self.syms.values()) if all_symbols else self.kconfig_syms

    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 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 get_top_level_items(self):
        """Returns a list containing the items (symbols, menus, choices, 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

    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.

        "# CONFIG_FOO is not set" within a .config file is treated specially
        and sets the user value of FOO to 'n'. The C implementation works the
        same way.

        filename: The .config file to load. $-references to existing
          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."""

        # Put this first so that a missing file doesn't screw up our state
        filename = os.path.expandvars(filename)
        line_feeder = _FileFeed(filename)

        self.config_filename = filename

        #
        # Read header
        #

        def is_header_line(line):
            return line is not None and line.startswith("#") and \
                   not _unset_re_match(line)

        self.config_header = None

        line = line_feeder.peek_next()
        if is_header_line(line):
            self.config_header = ""
            while is_header_line(line_feeder.peek_next()):
                self.config_header += line_feeder.get_next()[1:]
            # Remove trailing newline
            if self.config_header.endswith("\n"):
                self.config_header = self.config_header[:-1]

        #
        # Read assignments. Hotspot for some workloads.
        #

        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)

        # Invalidate everything to keep things simple. It might be possible to
        # improve performance for the case where multiple configurations are
        # loaded by only invalidating a symbol (and its dependent symbols) if
        # the new user value differs from the old. One complication would be
        # that symbols not mentioned in the .config must lose their user value
        # when replace = True, which is the usual case.
        if replace:
            self.unset_user_values()
        else:
            self._invalidate_all()

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

            line = line.rstrip()

            set_match = _set_re_match(line)
            if set_match:
                name, val = set_match.groups()

                if val.startswith('"'):
                    if len(val) < 2 or val[-1] != '"':
                        _parse_error(line, "malformed string literal",
                                     line_feeder.filename, line_feeder.linenr)
                    # Strip quotes and remove escapings. The unescaping
                    # procedure should be safe since " can only appear as \"
                    # inside the string.
                    val = val[1:-1].replace('\\"', '"').replace("\\\\", "\\")

                if name in self.syms:
                    sym = self.syms[name]
                    if sym.user_val is not None:
                        warn_override(line_feeder.filename, line_feeder.linenr,
                                      name, sym.user_val, val)

                    if sym.is_choice_sym:
                        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),
                                       line_feeder.filename,
                                       line_feeder.linenr)

                    sym._set_user_value_no_invalidate(val, True)
                else:
                    if self.print_undef_assign:
                        _stderr_msg('note: attempt to assign the value "{0}" '
                                    "to the undefined symbol {1}."
                                    .format(val, name),
                                    line_feeder.filename, line_feeder.linenr)
            else:
                unset_match = _unset_re_match(line)
                if unset_match:
                    name = unset_match.group(1)
                    if name in self.syms:
                        sym = self.syms[name]
                        if sym.user_val is not None:
                            warn_override(line_feeder.filename,
                                          line_feeder.linenr,
                                          name, sym.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.

        Kconfiglib makes sure the format matches what the C implementation
        would generate, down to whitespace. This eases testing.

        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."""

        for sym in self.syms_iter():
            sym.already_written = False

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

            # Build and write configuration
            conf_strings = []
            _make_block_conf(self.top_block, conf_strings.append)
            f.write("\n".join(conf_strings))
            f.write("\n")

    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 function 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.

        Syntax checking is somewhat lax, partly to be compatible with lax
        parsing in the C implementation."""
        return self._eval_expr(self._parse_expr(self._tokenize(s, True), # Feed
                                                None, # Current symbol/choice
                                                s))   # line

    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_iter():
            sym._unset_user_value_no_recursive_invalidate()

    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."""
        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 __str__(self):
        """Returns a string containing various information about the Config."""
        return _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
    #

    #
    # Kconfig parsing
    #

    def _parse_file(self, filename, parent, deps, visible_if_deps, res=None):
        """Parses the Kconfig file 'filename'. Returns a list with the Items in
        the file. See _parse_block() for the meaning of the parameters."""
        return self._parse_block(_FileFeed(filename), None, parent, deps,
                                 visible_if_deps, res)

    def _parse_block(self, line_feeder, end_marker, parent, deps,
                     visible_if_deps, res=None):
        """Parses a block, which is the contents of either a file or an if,
        menu, or choice statement. Returns a list with the Items in the block.

        line_feeder: A _FileFeed instance feeding lines from a file. The
          Kconfig language is line-based in practice.

        end_marker: The token that ends the block, e.g. T_ENDIF ("endif") for
           ifs. 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 ifs.

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

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

        block = [] if res is None else res

        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:
                line = self.end_line
                tokens = self.end_line_tokens
                tokens.unget_all()

                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.filename))
                    return block

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

            t0 = tokens.get_next()
            if t0 is None:
                continue

            # Cases are ordered roughly by frequency, which speeds things up a
            # bit

            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.append(sym)

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

            elif t0 == T_SOURCE:
                kconfig_file = tokens.get_next()
                exp_kconfig_file = self._expand_sym_refs(kconfig_file)
                g = glob.glob(self.base_dir + exp_kconfig_file)
                for s in g:
                    f = os.path.join(s)
                    if not os.path.exists(f):
                        raise IOError('{0}:{1}: sourced file "{2}" (expands to '
                              '"{3}") not found. Perhaps base_dir '
                              '(argument to Config.__init__(), currently '
                              '"{4}") is set to the wrong value.'
                              .format(line_feeder.filename,
                                  line_feeder.linenr,
                                  kconfig_file, exp_kconfig_file,
                                  self.base_dir))
                    # Add items to the same block
                    self._parse_file(s, parent, deps, visible_if_deps, block)

            elif t0 == end_marker:
                # We have reached the end of the block
                return block

            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,
                                            line_feeder.filename,
                                            line_feeder.linenr)
                # Add items to the same block
                self._parse_block(line_feeder, T_ENDIF, parent,
                                  _make_and(dep_expr, deps),
                                  visible_if_deps, block)

            elif t0 == T_COMMENT:
                comment = Comment()

                comment.config = self
                comment.parent = parent
                comment.filename = line_feeder.filename
                comment.linenr = line_feeder.linenr
                comment.text = tokens.get_next()

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

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

            elif t0 == T_MENU:
                menu = Menu()

                menu.config = self
                menu.parent = parent
                menu.filename = line_feeder.filename
                menu.linenr = line_feeder.linenr
                menu.title = tokens.get_next()

                self.menus.append(menu)
                block.append(menu)

                # 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))

            elif t0 == T_CHOICE:
                name = tokens.get_next()
                if name is None:
                    choice = Choice()
                    self.choices.append(choice)
                else:
                    # Named choice
                    choice = self.named_choices.get(name)
                    if choice is None:
                        choice = Choice()
                        choice.name = name
                        self.named_choices[name] = choice
                        self.choices.append(choice)

                choice.config = self
                choice.parent = parent

                choice.def_locations.append((line_feeder.filename,
                                             line_feeder.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, deps, visible_if_deps)

                choice._determine_actual_symbols()

                # If no type is specified for the choice, its type is that of
                # the first choice item with a specified type
                if choice.type == UNKNOWN:
                    for item in choice.actual_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.actual_symbols:
                    if item.type == UNKNOWN:
                        item.type = choice.type

                block.append(choice)

            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),
                               line_feeder.filename, line_feeder.linenr)
                self.mainmenu_text = text

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

    def _parse_properties(self, line_feeder, stmt, deps, visible_if_deps):
        """Parsing of properties for symbols, menus, choices, and comments.
        Takes care of propagating dependencies from enclosing menus and ifs."""

        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.filename
            linenr = line_feeder.linenr

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

            t0 = tokens.get_next()
            if t0 is None:
                continue

            # Cases are ordered roughly by frequency, which speeds things up a
            # bit

            if 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.orig_deps = _make_and(stmt.orig_deps, parsed_deps)
                else:
                    depends_on_expr = _make_and(depends_on_expr, parsed_deps)

            elif t0 == T_HELP:
                # Find first non-blank (not all-space) line and get its
                # indentation
                line = line_feeder.next_nonblank()
                if line is None:
                    stmt.help = ""
                    break
                indent = _indentation(line)
                if indent == 0:
                    # If the first non-empty lines has zero indent, there is no
                    # help text
                    stmt.help = ""
                    line_feeder.unget()
                    break

                # The help text goes on till the first non-empty line with less
                # indent
                help_lines = [_deindent(line, 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.unget()

            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 tokens.peek_next() is not None:
                    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_DEF_BOOL:
                stmt.type = BOOL
                if tokens.peek_next() is not None:
                    new_def_exprs.append(parse_val_and_cond(tokens, line,
                                                            filename, linenr))

            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_RANGE:
                low = tokens.get_next()
                high = tokens.get_next()
                stmt.referenced_syms.add(low)
                stmt.referenced_syms.add(high)

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

            elif t0 == T_DEF_TRISTATE:
                stmt.type = TRISTATE
                if tokens.peek_next() is not None:
                    new_def_exprs.append(parse_val_and_cond(tokens, line,
                                                            filename, linenr))

            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 email "
                                   "ulfalizer a.t Google's email service."""
                                   .format(stmt.name, env_var),
                                   filename, linenr)

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

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

                elif tokens.check(T_MODULES):
                    # To reduce warning spam, only warn if 'option modules' is
                    # set on some symbol that isn't MODULES, which should be
                    # safe. I haven't run into any projects that make use
                    # modules besides the kernel yet, and there it's likely to
                    # keep being called "MODULES".
                    if stmt.name != "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. "
                                   "(Note that modules are still supported -- "
                                   "Kconfiglib just assumes the symbol name "
                                   "MODULES, like older versions of the C "
                                   "implementation did when 'option modules' "
                                   "wasn't used.)",
                                   filename, linenr)

                elif tokens.check(T_ALLNOCONFIG_Y):
                    if not isinstance(stmt, Symbol):
                        _parse_error(line,
                                     "the 'allnoconfig_y' option is only "
                                     "valid for symbols",
                                     filename, linenr)
                    stmt.allnoconfig_y = True

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

            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_OPTIONAL:
                if not isinstance(stmt, Choice):
                    _parse_error(line,
                                 '"optional" is only valid for choices',
                                 filename,
                                 linenr)
                stmt.optional = True

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

        # Done parsing properties. Now propagate 'depends on' and enclosing
        # menu/if dependencies to expressions.

        # The set of symbols referenced directly by the statement plus all
        # symbols referenced by enclosing menus and ifs
        stmt.all_referenced_syms = stmt.referenced_syms | _get_expr_syms(deps)

        # Save original dependencies from enclosing menus and ifs
        stmt.deps_from_containing = deps

        if isinstance(stmt, (Menu, Comment)):
            stmt.dep_expr = _make_and(stmt.orig_deps, deps)
        else:
            # Symbol or Choice

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

            # Propagate dependencies to prompts

            if new_prompt is not None:
                # Propagate 'visible if' dependencies from enclosing menus
                prompt, cond_expr = new_prompt
                cond_expr = _make_and(cond_expr, visible_if_deps)
                # Propagate 'depends on' dependencies
                new_prompt = (prompt, _make_and(cond_expr, depends_on_expr))
                # Save original
                stmt.orig_prompts.append(new_prompt)
                # Finalize with dependencies from enclosing menus and ifs
                stmt.prompts.append((new_prompt[0],
                                     _make_and(new_prompt[1], deps)))

            # Propagate dependencies to defaults

            # Propagate 'depends on' dependencies
            new_def_exprs = [(val_expr, _make_and(cond_expr, depends_on_expr))
                             for val_expr, cond_expr in new_def_exprs]
            # Save original
            stmt.orig_def_exprs.extend(new_def_exprs)
            # Finalize with dependencies from enclosing menus and ifs
            stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
                                   for val_expr, cond_expr in new_def_exprs])

            # Propagate dependencies to selects

            # Only symbols can select
            if isinstance(stmt, Symbol):
                # Propagate 'depends on' dependencies
                new_selects = [(target, _make_and(cond_expr, depends_on_expr))
                               for target, cond_expr in new_selects]
                # Save original
                stmt.orig_selects.extend(new_selects)
                # Finalize with dependencies from enclosing menus and ifs
                for target, cond in new_selects:
                    target.rev_dep = _make_or(target.rev_dep,
                                              _make_and(stmt,
                                                        _make_and(cond, deps)))

    def _parse_expr(self, feed, cur_item, line, filename=None, linenr=None,
                    transform_m=True):
        """Parses an expression from the tokens in 'feed' using a simple
        top-down approach. The result has the form
        '(<operator>, [<parsed operands>])', where <operator> is e.g.
        kconfiglib.AND. If there is only one operand (i.e., no && or ||), then
        the operand is returned directly. This also goes for subexpressions.

        feed: _Feed instance containing the tokens for the expression.

        cur_item: The item (Symbol, Choice, Menu, or Comment) currently being
           parsed, or None if we're not parsing an item. 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().

        Expression grammar, in decreasing order of precedence:

        <expr> -> <symbol>
                  <symbol> '=' <symbol>
                  <symbol> '!=' <symbol>
                  '(' <expr> ')'
                  '!' <expr>
                  <expr> '&&' <expr>
                  <expr> '||' <expr>"""

        # Use instance variables to avoid having to pass these as arguments
        # through the top-down parser in _parse_expr_rec(), which is tedious
        # and obfuscates the code. A profiler run shows no noticeable
        # performance difference.
        self._cur_item = cur_item
        self._transform_m = transform_m
        self._line = line
        self._filename = filename
        self._linenr = linenr

        return self._parse_expr_rec(feed)

    def _parse_expr_rec(self, feed):
        or_term = self._parse_or_term(feed)
        if not feed.check(T_OR):
            # Common case -- no need for an OR node since it's just a single
            # operand
            return or_term
        or_terms = [or_term, self._parse_or_term(feed)]
        while feed.check(T_OR):
            or_terms.append(self._parse_or_term(feed))
        return (OR, or_terms)

    def _parse_or_term(self, feed):
        and_term = self._parse_factor(feed)
        if not feed.check(T_AND):
            # Common case -- no need for an AND node since it's just a single
            # operand
            return and_term
        and_terms = [and_term, self._parse_factor(feed)]
        while feed.check(T_AND):
            and_terms.append(self._parse_factor(feed))
        return (AND, and_terms)

    def _parse_factor(self, feed):
        token = feed.get_next()

        if isinstance(token, (Symbol, str)):
            if self._cur_item is not None and isinstance(token, Symbol):
                self._cur_item.referenced_syms.add(token)

            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._transform_m and (token is self.m or token == "m"):
                    return (AND, ["m", self._sym_lookup("MODULES")])
                return token

            relation = EQUAL if (feed.get_next() == T_EQUAL) else UNEQUAL
            token_2 = feed.get_next()
            if self._cur_item is not None and isinstance(token_2, Symbol):
                self._cur_item.referenced_syms.add(token_2)
            return (relation, token, token_2)

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

        if token == T_OPEN_PAREN:
            expr_parse = self._parse_expr_rec(feed)
            if not feed.check(T_CLOSE_PAREN):
                _parse_error(self._line, "missing end parenthesis",
                             self._filename, self._linenr)
            return expr_parse

        _parse_error(self._line, "malformed expression", self._filename,
                     self._linenr)

    def _tokenize(self, s, for_eval, 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.strip()
        if s == "" or s[0] == "#":
            return _Feed([])

        if for_eval:
            previous = None # The previous token seen
            tokens = []
            i = 0 # The current index in the string being tokenized

        else:
            # The initial word on a line is parsed specially. Let
            # command_chars = [A-Za-z0-9_]. Then
            #  - leading non-command_chars characters 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([])
            keyword = _get_keyword(initial_token_match.group(1))
            if keyword == T_HELP:
                # Avoid junk after "help", e.g. "---", being registered as a
                # symbol
                return _Feed([T_HELP])
            if keyword is None:
                # We expect a keyword as the first token
                _tokenization_error(s, filename, linenr)

            previous = keyword
            tokens = [keyword]
            # The current index in the string being tokenized
            i = initial_token_match.end()

        # _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 = _get_keyword(name)
                if keyword is not None:
                    # It's a keyword
                    append(keyword)
                elif previous in STRING_LEX:
                    # What would ordinarily be considered an identifier is
                    # treated as a string after certain tokens
                    append(name)
                else:
                    # It's a symbol name. _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, 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:
                # Not an identifier/keyword

                while i < strlen and s[i].isspace():
                    i += 1
                if i == strlen:
                    break
                c = s[i]
                i += 1

                # String literal (constant symbol)
                if c == '"' or c == "'":
                    if "\\" in s:
                        # Slow path: This could probably be sped up, but it's a
                        # very unusual case anyway.
                        quote = c
                        val = ""
                        while 1:
                            if i >= len(s):
                                _tokenization_error(s, filename, linenr)
                            c = s[i]
                            if c == quote:
                                break
                            if c == "\\":
                                if i + 1 >= len(s):
                                    _tokenization_error(s, filename, linenr)
                                val += s[i + 1]
                                i += 2
                            else:
                                val += c
                                i += 1
                        i += 1
                        append(val)
                    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, filename, linenr)
                        append(s[i:end])
                        i = end + 1

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

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

                elif c == "!":
                    if i < len(s) and s[i] == "=":
                        append(T_UNEQUAL)
                        i += 1
                    else:
                        append(T_NOT)

                elif c == "=": append(T_EQUAL)
                elif c == "(": append(T_OPEN_PAREN)
                elif c == ")": append(T_CLOSE_PAREN)
                elif c == "#": break # Comment

                else: continue # Invalid characters are ignored

            previous = tokens[-1]

        return _Feed(tokens)

    def _sym_lookup(self, name, for_eval=False):
        """Fetches the symbol 'name' from the symbol table, creating and
        registering it if it does not exist. If 'for_eval' is True, the symbol
        won't be added to the symbol table if it does not exist -- this is for
        Config.eval()."""
        if name in self.syms:
            return self.syms[name]

        new_sym = Symbol()
        new_sym.config = self
        new_sym.name = name
        if for_eval:
            self._warn("no symbol {0} in configuration".format(name))
        else:
            self.syms[name] = new_sym
        return new_sym

    #
    # Expression evaluation
    #

    def _eval_expr(self, expr):
        """Evaluates an expression to "n", "m", or "y"."""

        # Handles e.g. an "x if y" condition where the "if y" part is missing.
        if expr is None:
            return "y"

        res = self._eval_expr_rec(expr)
        if res == "m":
            # 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 demoted to "n" instead.
            modules_sym = self.syms.get("MODULES")
            if modules_sym is None or modules_sym.get_value() != "y":
                return "y"
        return res

    def _eval_expr_rec(self, expr):
        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"

        # Ordered by frequency

        if expr[0] == AND:
            res = "y"
            for subexpr in expr[1]:
                ev = self._eval_expr_rec(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 expr[0] == NOT:
            ev = self._eval_expr_rec(expr[1])
            if ev == "y":
                return "n"
            return "y" if (ev == "n") else "m"

        if expr[0] == OR:
            res = "n"
            for subexpr in expr[1]:
                ev = self._eval_expr_rec(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 expr[0] == EQUAL:
            return "y" if (_str_val(expr[1]) == _str_val(expr[2])) else "n"

        if expr[0] == UNEQUAL:
            return "y" if (_str_val(expr[1]) != _str_val(expr[2])) else "n"

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

    def _eval_min(self, e1, e2):
        """Returns the minimum value of the two expressions. Equates None with
        'y'."""
        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):
        """Returns the maximum value of the two expressions. Equates None with
        'y'."""
        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

    #
    # Dependency tracking (for caching and invalidation)
    #

    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."""

        # 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_iter():
            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_sym:
                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 _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

        def transform_y_m_n(item):
            if item is self.y: return "y"
            if item is self.m: return "m"
            if item is self.n: return "n"
            return item

        left = transform_y_m_n(left)
        right = transform_y_m_n(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 == "y" or right == "m")) or \
           (relation == UNEQUAL and right == "n"):
            return left
        return None

    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

            if expr[0] in (EQUAL, UNEQUAL):
                return self._eq_to_sym(expr) is sym
            if expr[0] == AND:
                for and_expr in expr[1]:
                    if rec(and_expr):
                        return True
            return False

        return rec(expr)

    def _invalidate_all(self):
        for sym in self.syms_iter():
            sym._invalidate()

    #
    # Printing and misc.
    #

    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_match = _sym_ref_re_search(s)
            if sym_ref_match is None:
                return s

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

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

    def _expr_val_str(self, expr, no_value_str="(none)",
                      get_val_instead_of_eval=False):
        """Printing helper. Returns a string with 'expr' and its value.

        no_value_str: String to return when 'expr' is missing (None).

        get_val_instead_of_eval: Assume 'expr' is a symbol or string (constant
          symbol) and get its value directly instead of evaluating it to a
          tristate value."""

        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 _get_sym_or_choice_str_rest(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_val_str = "(no user value)" if sc.user_val is None else \
                       s(sc.user_val)

        # Build prompts string
        if not 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 {1}'.format(prompt,
                                             self._expr_val_str(cond_expr)))
	    prompts_str =  "\n * "
            prompts_str += "\n * ".join(prompts_str_rows)

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

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

        #
        # Symbol-specific stuff
        #

        if isinstance(sc, Symbol):
            # Build ranges string
            if isinstance(sc, Symbol):
                if not 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 * "
                    ranges_str += "\n * ".join(ranges_str_rows)

            # Build default values string
            if not 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 * "
                defaults_str += "\n * ".join(defaults_str_rows)

            # Build selects string
            if not 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(" :ref:`CONFIG_{0}`".format(target.name))
                    else:
                        selects_str_rows.append(
                          " :ref:`CONFIG_{0}` if {1}".format(target.name,
                                               self._expr_val_str(cond_expr)))
		selects_str = "\n * "
                selects_str += "\n * ".join(selects_str_rows)

            res = _lines(":Symbol:           " +
                           ("(no name)" if sc.name is None else sc.name),
                         ":Type:             " + TYPENAME[sc.type],
                         ":Value:            " + s(sc.get_value()),
                         ":User value:       " + user_val_str,
                         ":Visibility:       " + s(_get_visibility(sc)),
                         ":Is choice item:   " + BOOL_STR[sc.is_choice_sym],
                         ":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 += _lines(":Ranges:", ranges_str + "\n")
            res += _lines(":Prompts:",
                          prompts_str,
                          ":Default values:",
                          defaults_str,
                          ":Selects:",
                          selects_str,
                          ":Reverse (select-related) dependencies:",
                          " (no reverse dependencies)" if sc.rev_dep == "n"
                            else " " + self._expr_val_str(sc.rev_dep),
                          ":Additional dependencies from enclosing menus "
                            "and ifs:",
                          additional_deps_str,
                          ":Locations:" + locations_str.replace(self.srctree + "/", ""))

            return res

        #
        # Choice-specific stuff
        #

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

        # Build default values string
        if not 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 {1}".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.actual_symbols]
        syms_string = " ".join(names) if names else "(empty)"

        return _lines("Choice",
                      "Name (for named choices): " +
                        ("(no name)" if sc.name is None else sc.name),
                      "Type            : " + TYPENAME[sc.type],
                      "Selected symbol : " + sel_str,
                      "User value      : " + user_val_str,
                      "Mode            : " + s(sc.get_mode()),
                      "Visibility      : " + s(_get_visibility(sc)),
                      "Optional        : " + BOOL_STR[sc.optional],
                      "Prompts:",
                      prompts_str,
                      "Defaults:",
                      defaults_str,
                      "Choice symbols:",
                      " " + syms_string,
                      "Additional dependencies from enclosing menus and "
                        "ifs:",
                      additional_deps_str,
                      "Locations:" + locations_str)

    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_val_str = "(no user value)" if sc.user_val is None else \
                       s(sc.user_val)

        # Build prompts string
        if not 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 {1}'.format(prompt,
                                             self._expr_val_str(cond_expr)))
	    prompts_str = "\n  * "
            prompts_str += "\n  * ".join(prompts_str_rows)

        # Build locations string
        if not 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-ifs string
        additional_deps_str = " " + \
          self._expr_val_str(sc.deps_from_containing,
                             "(no additional dependencies)")

        #
        # Symbol-specific stuff
        #

        if isinstance(sc, Symbol):
            # Build ranges string
            if isinstance(sc, Symbol):
                if not 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 * "
                    ranges_str += "\n * ".join(ranges_str_rows)

            # Build default values string
            if not 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 * "
                defaults_str += "\n * ".join(defaults_str_rows)

            # Build selects string
            if not 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(" :ref:`CONFIG_{0}`".format(target.name))
                    else:
                        selects_str_rows.append(
                          " :ref:`CONFIG_{0}` if {1}".format(target.name,
                                               self._expr_val_str(cond_expr)))
                selects_str = "\n".join(selects_str_rows)

            res = _lines("Symbol " +
                           ("(no name)" if sc.name is None else sc.name),
                         "Type           : " + TYPENAME[sc.type],
                         "Value          : " + s(sc.get_value()),
                         "User value     : " + user_val_str,
                         "Visibility     : " + s(_get_visibility(sc)),
                         "Is choice item : " + BOOL_STR[sc.is_choice_sym],
                         "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 += _lines(":Ranges:", ranges_str + "\n")
            res += _lines("Prompts:",
                          prompts_str,
                          "Default values:",
                          defaults_str,
                          "Selects:",
                          selects_str,
                          "Reverse (select-related) dependencies:",
                          " (no reverse dependencies)" if sc.rev_dep == "n"
                            else " " + self._expr_val_str(sc.rev_dep),
                          "Additional dependencies from enclosing menus "
                            "and ifs:",
                          additional_deps_str,
                          "Locations:" + locations_str)

            return res

        #
        # Choice-specific stuff
        #

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

        # Build default values string
        if not 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 {1}".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.actual_symbols]
        syms_string = " ".join(names) if names else "(empty)"

        return _lines("Choice",
                      "Name (for named choices): " +
                        ("(no name)" if sc.name is None else sc.name),
                      "Type            : " + TYPENAME[sc.type],
                      "Selected symbol : " + sel_str,
                      "User value      : " + user_val_str,
                      "Mode            : " + s(sc.get_mode()),
                      "Visibility      : " + s(_get_visibility(sc)),
                      "Optional        : " + BOOL_STR[sc.optional],
                      "Prompts:",
                      prompts_str,
                      "Defaults:",
                      defaults_str,
                      "Choice symbols:",
                      " " + syms_string,
                      "Additional dependencies from enclosing menus and "
                        "ifs:",
                      additional_deps_str,
                      "Locations:" + locations_str)

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

class Item(object):

    """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. Short for
        isinstance(item, kconfiglib.Symbol)."""
        return isinstance(self, Symbol)

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

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

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

class Symbol(Item):

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

    config FOO
        ..."""

    #
    # Public interface
    #

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

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

    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_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_help(self):
        """Returns the help text of the symbol, or None if the symbol has no
        help text."""
        return self.help

    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_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 get_value(self):
        """Calculate and return the value of the symbol. See also
        Symbol.set_user_value()."""

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

        # 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_val = self.name
            return self.name

        new_val = DEFAULT_VALUE[self.type]
        vis = _get_visibility(self)

        # This is easiest to calculate together with the value
        self.write_to_conf = False

        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 _get_visibility()
            if self.is_choice_sym:
                if vis != "n":
                    choice = self.parent
                    mode = choice.get_mode()

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

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

            else:
                # If the symbol is visible and has a user value, use that.
                # Otherwise, look at defaults.
                use_defaults = True

                if vis != "n":
                    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 (select-related) 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 == INT or self.type == HEX:
            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 = _str_val(l)
                    high_str = _str_val(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 = _str_val(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))

        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 = _str_val(val_expr)
                        break

        self.cached_val = new_val
        return new_val

    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_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", pinning it
        if rev_dep == "m" and self.type == BOOL:
            return None
        vis = _get_visibility(self)
        if TRI_TO_INT[vis] > TRI_TO_INT[rev_dep]:
            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", pinning it
        if rev_dep == "m" and self.type == BOOL:
            return None
        if TRI_TO_INT[_get_visibility(self)] > TRI_TO_INT[rev_dep]:
            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", pinning it
        if rev_dep == "m" and self.type == BOOL:
            return []
        res = ["n", "m", "y"][TRI_TO_INT[rev_dep] :
                              TRI_TO_INT[_get_visibility(self)] + 1]
        return res if len(res) > 1 else []

    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 _get_visibility(self)

    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 ifs 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 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 is_modifiable(self):
        """Returns True if the value of the symbol could be modified by calling
        Symbol.set_user_value().

        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", pinning it
            if rev_dep == "m" and self.type == BOOL:
                return False
            return TRI_TO_INT[_get_visibility(self)] > TRI_TO_INT[rev_dep]
        return _get_visibility(self) != "n"

    def is_defined(self):
        """Returns False if the symbol is referred to in the Kconfig but never
        actually defined."""
        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."""
        return self.is_special_

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

    def has_ranges(self):
        """Returns True if the symbol is of type INT or HEX and has ranges that
        limit what values it can take on."""
        return bool(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())."""
        return self.is_choice_sym

    def is_choice_selection(self):
        """Returns True if the symbol is contained in a choice statement and is
        the selected item. Equivalent to

        sym.is_choice_symbol() and sym.get_parent().get_selection() is sym"""
        return self.is_choice_sym and self.parent.get_selection() is self

    def is_allnoconfig_y(self):
        """Returns True if the symbol has the 'allnoconfig_y' option set."""
        return self.allnoconfig_y

    def rest(self):
        """Returns a string containing various information about the symbol."""
        return self.config._get_sym_or_choice_str_rest(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."""

        self.name = None
        self.type = UNKNOWN
        self.prompts = []
        self.def_exprs = [] # 'default' properties
        self.ranges = [] # 'range' properties (for int and hex)
        self.help = None # Help text
        self.rev_dep = "n" # Reverse (select-related) dependencies
        self.config = None
        self.parent = None

        self.user_val = None # Value set by user

        # The prompt, default value and select conditions without any
        # dependencies from menus and ifs propagated to them
        self.orig_prompts = []
        self.orig_def_exprs = []
        self.orig_selects = []

        # Dependencies inherited from containing menus and ifs
        self.deps_from_containing = 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 ifs
        self.all_referenced_syms = set()

        # 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 = []

        # Populated in Config._build_dep() after parsing. Links 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().
        self.dep = set()

        # Cached values

        # Caches the calculated value
        self.cached_val = None
        # Caches the visibility, which acts as an upper bound on the value
        self.cached_visibility = None
        # Caches the total list of dependent symbols. Calculated in
        # _get_dependent().
        self.cached_deps = None

        # Flags

        # Does the symbol have an entry in the Kconfig file? The trailing
        # underscore avoids a collision with is_defined().
        self.is_defined_ = False
        # Should the symbol get an entry in .config?
        self.write_to_conf = False
        # Set to true when _make_conf() is called on a symbol, so that symbols
        # defined in multiple locations only get one .config entry. We need to
        # reset it prior to writing out a new .config.
        self.already_written = False
        # This is set to True for "actual" choice symbols; see
        # Choice._determine_actual_symbols().
        self.is_choice_sym = 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_val, 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
        # Does the symbol have the 'allnoconfig_y' option set?
        self.allnoconfig_y = False

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

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

        self.cached_val = None
        self.cached_visibility = 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]
            if self.config.print_undef_assign:
                _stderr_msg('note: 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 == "y" or v == "n")   ) or
                (self.type == TRISTATE and (v == "y" or v == "m" or
                                            v == "n")               ) 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 not 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_sym 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_sym:
            self.parent._unset_user_value()

    def _make_conf(self, append_fn):
        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 == "y" or val == "m":
                append_fn("CONFIG_{0}={1}".format(self.name, val))
            else:
                append_fn("# CONFIG_{0} is not set".format(self.name))

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

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

        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.dep)
        for s in self.dep:
            res |= s._get_dependent()

        if self.is_choice_sym:
            # Choice symbols also depend (recursively) on their siblings. The
            # siblings are not included in 'dep' to avoid dependency loops.
            for sibling in self.parent.actual_symbols:
                if sibling is not self:
                    res.add(sibling)
                    res |= sibling.dep
                    for s in sibling.dep:
                        res |= s._get_dependent()

        self.cached_deps = res
        return res

    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 not 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_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_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 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

        res = []
        for item in self.block:
            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_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_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 __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 _lines("Menu",
                      "Title                     : " + self.title,
                      "'depends on' dependencies : " + depends_on_str,
                      "'visible if' dependencies : " + visible_if_str,
                      "Additional dependencies from enclosing menus and "
                        "ifs:",
                      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.title = None
        self.dep_expr = None
        self.visible_if_expr = None
        self.block = None
        self.config = None
        self.parent = None

        # Dependency expression without dependencies from enclosing menus and
        # ifs propagated
        self.orig_deps = None

        # Dependencies inherited from containing menus and ifs
        self.deps_from_containing = 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 ifs
        self.all_referenced_syms = None

        self.filename = None
        self.linenr = None

    def _make_conf(self, append_fn):
        if self.config._eval_expr(self.dep_expr) != "n" and \
           self.config._eval_expr(self.visible_if_expr) != "n":
            append_fn("\n#\n# {0}\n#".format(self.title))
        _make_block_conf(self.block, append_fn)

class Choice(Item):

    """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_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_type(self):
        """Returns the type of the choice. See Symbol.get_type()."""
        return self.type

    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_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_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_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 _get_visibility(self.user_val) == "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 not 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 _get_visibility(chosen_symbol) != "n":
            return chosen_symbol
        # Otherwise, pick the first visible symbol
        for sym in self.actual_symbols:
            if _get_visibility(sym) != "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_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

    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_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_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 _get_visibility(self)

    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, _get_visibility(self))

        # 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 choice has the 'optional' flag set (and so will
        default to "n" mode)."""
        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."""

        self.name = None # Yes, choices can be named
        self.type = UNKNOWN
        self.prompts = []
        self.def_exprs = [] # 'default' properties
        self.help = None # Help text
        self.block = None # List of contained items
        self.config = None
        self.parent = None

        self.user_val = None
        self.user_mode = 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 prompts and default values without any dependencies from
        # enclosing menus and ifs propagated
        self.orig_prompts = []
        self.orig_def_exprs = []

        # Dependencies inherited from containing menus and ifs
        self.deps_from_containing = None
        # 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 ifs
        self.all_referenced_syms = set()

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

        # Cached values
        self.cached_selection = None
        self.cached_visibility = None

        self.optional = False

    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. (This is 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
        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_sym 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 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 self.block:
            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_sym
                    stack.append(item)
                    break
                else:
                    stack.pop()
            else:
                item.is_choice_sym = 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):
        self.cached_selection = None
        self.cached_visibility = None

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

    def _make_conf(self, append_fn):
        _make_block_conf(self.block, append_fn)

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_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_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 get_visibility(self):
        """Returns the visibility of the comment. See also
        Symbol.get_visibility()."""
        return self.config._eval_expr(self.dep_expr)

    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 __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 _lines("Comment",
                      "Text: "         + str(self.text),
                      "Dependencies: " + dep_str,
                      "Additional dependencies from enclosing menus and "
                        "ifs:",
                      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.text = None
        self.dep_expr = None
        self.config = None
        self.parent = None

        # Dependency expression without dependencies from enclosing menus and
        # ifs propagated
        self.orig_deps = None

        # Dependencies inherited from containing menus and ifs
        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 ifs
        self.all_referenced_syms = None

        self.filename = None
        self.linenr = None

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

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

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

#
# Public 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."""
    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."""
    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."""
    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."""
    return TRI_TO_INT[v1] >= TRI_TO_INT[v2]

#
# Internal classes
#

class _Feed(object):

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

    # This would be more helpful on the item classes, but would remove some
    # flexibility
    __slots__ = ['items', 'length', 'i']

    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 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 and self.items[self.i] == token:
            self.i += 1
            return True
        return False

    def unget_all(self):
        self.i = 0

class _FileFeed(object):

    """Feeds lines from a file. Keeps track of the filename and current line
    number. Joins any line ending in \\ with the following line. We need to be
    careful to get the line number right in the presence of continuation
    lines."""

    __slots__ = ['filename', 'lines', 'length', 'linenr']

    def __init__(self, filename):
        self.filename = _clean_up_path(filename)
        with open(filename, "r") as f:
            # No interleaving of I/O and processing yet. Don't know if it would
            # help.
            self.lines = f.readlines()
        self.length = len(self.lines)
        self.linenr = 0

    def get_next(self):
        if self.linenr >= self.length:
            return None
        line = self.lines[self.linenr]
        self.linenr += 1
        while line.endswith("\\\n"):
            line = line[:-2] + self.lines[self.linenr]
            self.linenr += 1
        return line

    def peek_next(self):
        linenr = self.linenr
        if linenr >= self.length:
            return None
        line = self.lines[linenr]
        while line.endswith("\\\n"):
            linenr += 1
            line = res[:-2] + self.lines[linenr]
        return line

    def unget(self):
        self.linenr -= 1
        while self.lines[self.linenr].endswith("\\\n"):
            self.linenr -= 1

    def next_nonblank(self):
        """Removes lines up to and including the next non-blank (not all-space)
        line and returns it. Returns None if there are no more non-blank
        lines."""
        while 1:
            line = self.get_next()
            if line is None or not line.isspace():
                return line

#
# Internal functions
#

def _get_visibility(sc):
    """Symbols and Choices have a "visibility" that acts as an upper bound on
    the values a user can set for them, corresponding to the visibility in e.g.
    'make menuconfig'. This function calculates the visibility for the Symbol
    or Choice 'sc' -- the logic is nearly identical."""
    if sc.cached_visibility is None:
        vis = "n"
        for _, cond_expr in sc.prompts:
            vis = sc.config._eval_max(vis, cond_expr)

        if isinstance(sc, Symbol) and sc.is_choice_sym:
            vis = sc.config._eval_min(vis, _get_visibility(sc.parent))

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

        sc.cached_visibility = vis

    return sc.cached_visibility

def _make_and(e1, e2):
    """Constructs an AND (&&) expression. Performs trivial simplification.
    Nones equate to 'y'.

    Note: returns None if e1 == e2 == None."""
    if e1 is None or e1 == "y":
        return e2
    if e2 is None or e2 == "y":
        return e1

    # Prefer to merge argument lists if possible to reduce the number of nodes

    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])

def _make_or(e1, e2):
    """Constructs an OR (||) expression. Performs trivial simplification and
    avoids Nones. Nones equate to 'y', which is usually what we want, but needs
    to be kept in mind."""

    # 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

    # Prefer to merge argument lists if possible to reduce the number of nodes

    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])

def _get_expr_syms_rec(expr, res):
    """_get_expr_syms() helper. Recurses through expressions."""
    if isinstance(expr, Symbol):
        res.add(expr)
    elif isinstance(expr, str):
        return
    elif expr[0] == AND or expr[0] == OR:
        for term in expr[1]:
            _get_expr_syms_rec(term, res)
    elif expr[0] == NOT:
        _get_expr_syms_rec(expr[1], res)
    elif expr[0] == EQUAL or expr[0] == UNEQUAL:
        if isinstance(expr[1], Symbol):
            res.add(expr[1])
        if isinstance(expr[2], Symbol):
            res.add(expr[2])
    else:
        _internal_error("Internal error while fetching symbols from an "
                        "expression with token stream {0}.".format(expr))

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

def _str_val(obj):
    """Returns the value of obj as a string. If obj is not a string (constant
    symbol), it must be a Symbol."""
    return obj if isinstance(obj, str) else obj.get_value()

def _make_block_conf(block, append_fn):
    """Returns a list of .config strings for a block (list) of items."""

    # 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.
    for item in block:
        item._make_conf(append_fn)

def _sym_str_string(sym_or_str):
    if isinstance(sym_or_str, str):
        return '"' + sym_or_str + '"'
    return sym_or_str.name

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 not 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_rec(expr):
    if expr is None:
        return [""]

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

    if expr[0] in (AND, OR):
        return _intersperse(expr[1], expr[0])

    if expr[0] == 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 expr[0] in (EQUAL, UNEQUAL):
        return [_sym_str_string(expr[1]),
                OP_TO_STR[expr[0]],
                _sym_str_string(expr[2])]

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

def _indentation(line):
    """Returns the length of the line's leading whitespace, treating tab stops
    as being spaced 8 characters apart."""
    line = line.expandtabs()
    return len(line) - len(line.lstrip())

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 _lines(*args):
    """Returns a string consisting 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 _clean_up_path(path):
    """Strips an initial "./" and any trailing slashes from 'path'."""
    if path.startswith("./"):
        path = path[2:]
    return path.rstrip("/")

def _stderr_msg(msg, filename, linenr):
    if filename is not None:
        sys.stderr.write("{0}:{1}: ".format(_clean_up_path(filename), linenr))
    sys.stderr.write(msg + "\n")

def _tokenization_error(s, filename, linenr):
    loc = "" if filename is None else "{0}:{1}: ".format(filename, linenr)
    raise Kconfig_Syntax_Error("{0}Couldn't tokenize '{1}'"
                               .format(loc, s.strip()))

def _parse_error(s, msg, filename, linenr):
    loc = "" if filename is None else "{0}:{1}: ".format(filename, linenr)
    raise Kconfig_Syntax_Error("{0}Couldn't parse '{1}'{2}"
                               .format(loc, s.strip(),
                                       "." if msg is None else ": " + msg))

def _internal_error(msg):
    raise Internal_Error(msg +
      "\nSorry! You may want to send an email to ulfalizer a.t Google's "
      "email service to tell me about this. Include the message above and the "
      "stack trace and describe what you were doing.")

#
# Internal global constants
#

# Tokens
(T_AND, T_OR, 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_ALLNOCONFIG_Y, T_ENV,
 T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(39)

# The leading underscore before the function assignments below prevent pydoc
# from listing them. The constants could be hidden too, but they're fairly
# obviously internal anyway, so don't bother spamming the code.

# Keyword to token map. Note that the get() method is assigned directly as a
# small optimization.
_get_keyword = \
  {"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, "allnoconfig_y": T_ALLNOCONFIG_Y,
   "env": T_ENV, "defconfig_list": T_DEFCONFIG_LIST, "modules": T_MODULES,
   "visible": T_VISIBLE}.get

# 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(). Also eats trailing
# whitespace as an optimization.
_initial_token_re_match = re.compile(r"[^\w]*(\w+)\s*").match

# Matches an identifier/keyword optionally preceded by whitespace. Also eats
# trailing whitespace as an optimization.
_id_keyword_re_match = re.compile(r"\s*([\w./-]+)\s*").match

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

# Regular expression for finding $-references to symbols in strings
_sym_ref_re_search = re.compile(r"\$[A-Za-z0-9_]+").search

# Integers representing symbol types
UNKNOWN, BOOL, TRISTATE, STRING, HEX, INT = range(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
AND, OR, NOT, EQUAL, UNEQUAL = range(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}
