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

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

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

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

For the Linux kernel, scripts are run using

 $ make scriptconfig [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

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

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

        Returns a list or warnings (hopefully empty)
        """

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

            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 or choice, 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)
                f = os.path.join(self.base_dir, exp_kconfig_file)
                if not os.path.exists(f):
                    raise IOError('{0}:{1}: sourced file "{2}" (expands to '
                                  '"{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(f, 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 or t0 == T_IMPLY:
                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(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".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".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".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(" {0}".format(target.name))
                    else:
                        selects_str_rows.append(
                          " {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."""
        msg = _build_msg("warning: " + msg, filename, linenr)
        if self.print_warnings:
            sys.stderr.write(msg + "\n")
        self._warnings.append(msg)

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 __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 = line[:-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 _build_msg(msg, filename, linenr):
    if filename is not None:
        msg = "{0}:{1}: ".format(_clean_up_path(filename), linenr) + msg
    return msg

def _stderr_msg(msg, filename, linenr):
    sys.stderr.write(_build_msg(msg, filename, linenr) + "\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_IMPLY, T_RANGE, T_OPTION, T_ALLNOCONFIG_Y, T_ENV,
 T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(40)

# 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,
   "imply": T_IMPLY, "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}
