ARM: imx6q_logic: Fix MMC2 booting
[oweals/u-boot.git] / tools / buildman / kconfiglib.py
1 # SPDX-License-Identifier: ISC
2 #
3 # Author: Ulf Magnusson
4 #   https://github.com/ulfalizer/Kconfiglib
5
6 # This is Kconfiglib, a Python library for scripting, debugging, and extracting
7 # information from Kconfig-based configuration systems. To view the
8 # documentation, run
9 #
10 #  $ pydoc kconfiglib
11 #
12 # or, if you prefer HTML,
13 #
14 #  $ pydoc -w kconfiglib
15 #
16 # The examples/ subdirectory contains examples, to be run with e.g.
17 #
18 #  $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
19 #
20 # Look in testsuite.py for the test suite.
21
22 """
23 Kconfiglib is a Python library for scripting and extracting information from
24 Kconfig-based configuration systems. Features include the following:
25
26  - Symbol values and properties can be looked up and values assigned
27    programmatically.
28  - .config files can be read and written.
29  - Expressions can be evaluated in the context of a Kconfig configuration.
30  - Relations between symbols can be quickly determined, such as finding all
31    symbols that reference a particular symbol.
32  - Highly compatible with the scripts/kconfig/*conf utilities. The test suite
33    automatically compares outputs between Kconfiglib and the C implementation
34    for a large number of cases.
35
36 For the Linux kernel, scripts are run using
37
38  $ make scriptconfig [ARCH=<arch>] SCRIPT=<path to script> [SCRIPT_ARG=<arg>]
39
40 Using the 'scriptconfig' target ensures that required environment variables
41 (SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly.
42
43 Scripts receive the name of the Kconfig file to load in sys.argv[1]. As of
44 Linux 4.1.0-rc5, this is always "Kconfig" from the kernel top-level directory.
45 If an argument is provided with SCRIPT_ARG, it appears as sys.argv[2].
46
47 To get an interactive Python prompt with Kconfiglib preloaded and a Config
48 object 'c' created, run
49
50  $ make iscriptconfig [ARCH=<arch>]
51
52 Kconfiglib supports both Python 2 and Python 3. For (i)scriptconfig, the Python
53 interpreter to use can be passed in PYTHONCMD, which defaults to 'python'. PyPy
54 works well too, and might give a nice speedup for long-running jobs.
55
56 The examples/ directory contains short example scripts, which can be run with
57 e.g.
58
59  $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
60
61 or
62
63  $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG=kernel
64
65 testsuite.py contains the test suite. See the top of the script for how to run
66 it.
67
68 Credits: Written by Ulf "Ulfalizer" Magnusson
69
70 Send bug reports, suggestions and other feedback to ulfalizer a.t Google's
71 email service. Don't wrestle with internal APIs. Tell me what you need and I
72 might add it in a safe way as a client API instead."""
73
74 import os
75 import platform
76 import re
77 import sys
78
79 # File layout:
80 #
81 # Public classes
82 # Public functions
83 # Internal classes
84 # Internal functions
85 # Internal global constants
86
87 # Line length: 79 columns
88
89 #
90 # Public classes
91 #
92
93 class Config(object):
94
95     """Represents a Kconfig configuration, e.g. for i386 or ARM. This is the
96     set of symbols and other items appearing in the configuration together with
97     their values. Creating any number of Config objects -- including for
98     different architectures -- is safe; Kconfiglib has no global state."""
99
100     #
101     # Public interface
102     #
103
104     def __init__(self, filename="Kconfig", base_dir=None, print_warnings=True,
105                  print_undef_assign=False):
106         """Creates a new Config object, representing a Kconfig configuration.
107         Raises Kconfig_Syntax_Error on syntax errors.
108
109         filename (default: "Kconfig"): The base Kconfig file of the
110            configuration. For the Linux kernel, you'll probably want "Kconfig"
111            from the top-level directory, as environment variables will make
112            sure the right Kconfig is included from there
113            (arch/<architecture>/Kconfig). If you are using Kconfiglib via 'make
114            scriptconfig', the filename of the base base Kconfig file will be in
115            sys.argv[1].
116
117         base_dir (default: None): The base directory relative to which 'source'
118            statements within Kconfig files will work. For the Linux kernel this
119            should be the top-level directory of the kernel tree. $-references
120            to existing environment variables will be expanded.
121
122            If None (the default), the environment variable 'srctree' will be
123            used if set, and the current directory otherwise. 'srctree' is set
124            by the Linux makefiles to the top-level kernel directory. A default
125            of "." would not work with an alternative build directory.
126
127         print_warnings (default: True): Set to True if warnings related to this
128            configuration should be printed to stderr. This can be changed later
129            with Config.set_print_warnings(). It is provided as a constructor
130            argument since warnings might be generated during parsing.
131
132         print_undef_assign (default: False): Set to True if informational
133            messages related to assignments to undefined symbols should be
134            printed to stderr for this configuration. Can be changed later with
135            Config.set_print_undef_assign()."""
136
137         # The set of all symbols, indexed by name (a string)
138         self.syms = {}
139         # Python 2/3 compatibility hack. This is the only one needed.
140         self.syms_iter = self.syms.values if sys.version_info[0] >= 3 else \
141                          self.syms.itervalues
142
143         # The set of all defined symbols in the configuration in the order they
144         # appear in the Kconfig files. This excludes the special symbols n, m,
145         # and y as well as symbols that are referenced but never defined.
146         self.kconfig_syms = []
147
148         # The set of all named choices (yes, choices can have names), indexed
149         # by name (a string)
150         self.named_choices = {}
151
152         # Lists containing all choices, menus and comments in the configuration
153         self.choices = []
154         self.menus = []
155         self.comments = []
156
157         def register_special_symbol(type_, name, val):
158             sym = Symbol()
159             sym.is_special_ = True
160             sym.is_defined_ = True
161             sym.config = self
162             sym.name = name
163             sym.type = type_
164             sym.cached_val = val
165             self.syms[name] = sym
166             return sym
167
168         # The special symbols n, m and y, used as shorthand for "n", "m" and
169         # "y"
170         self.n = register_special_symbol(TRISTATE, "n", "n")
171         self.m = register_special_symbol(TRISTATE, "m", "m")
172         self.y = register_special_symbol(TRISTATE, "y", "y")
173         # DEFCONFIG_LIST uses this
174         register_special_symbol(STRING, "UNAME_RELEASE", platform.uname()[2])
175
176         # The symbol with "option defconfig_list" set, containing a list of
177         # default .config files
178         self.defconfig_sym = None
179
180         # See Symbol.get_(src)arch()
181         self.arch = os.environ.get("ARCH")
182         self.srcarch = os.environ.get("SRCARCH")
183
184         # If you set CONFIG_ in the environment, Kconfig will prefix all symbols
185         # with its value when saving the configuration, instead of using the default, "CONFIG_".
186         self.config_prefix = os.environ.get("CONFIG_")
187         if self.config_prefix is None:
188             self.config_prefix = "CONFIG_"
189
190         # See Config.__init__(). We need this for get_defconfig_filename().
191         self.srctree = os.environ.get("srctree")
192         if self.srctree is None:
193             self.srctree = "."
194
195         self.filename = filename
196         self.base_dir = self.srctree if base_dir is None else \
197                         os.path.expandvars(base_dir)
198
199         # The 'mainmenu' text
200         self.mainmenu_text = None
201
202         # The filename of the most recently loaded .config file
203         self.config_filename = None
204         # The textual header of the most recently loaded .config, uncommented
205         self.config_header = None
206
207         self.print_warnings = print_warnings
208         self.print_undef_assign = print_undef_assign
209         self._warnings = []
210
211         # For parsing routines that stop when finding a line belonging to a
212         # different construct, these holds that line and the tokenized version
213         # of that line. The purpose is to avoid having to re-tokenize the line,
214         # which is inefficient and causes problems when recording references to
215         # symbols.
216         self.end_line = None
217         self.end_line_tokens = None
218
219         # See the comment in _parse_expr().
220         self._cur_item = None
221         self._line = None
222         self._filename = None
223         self._linenr = None
224         self._transform_m = None
225
226         # Parse the Kconfig files
227         self.top_block = []
228         self._parse_file(filename, None, None, None, self.top_block)
229
230         # Build Symbol.dep for all symbols
231         self._build_dep()
232
233     def get_arch(self):
234         """Returns the value the environment variable ARCH had at the time the
235         Config instance was created, or None if ARCH was not set. For the
236         kernel, this corresponds to the architecture being built for, with
237         values such as "i386" or "mips"."""
238         return self.arch
239
240     def get_srcarch(self):
241         """Returns the value the environment variable SRCARCH had at the time
242         the Config instance was created, or None if SRCARCH was not set. For
243         the kernel, this corresponds to the particular arch/ subdirectory
244         containing architecture-specific code."""
245         return self.srcarch
246
247     def get_srctree(self):
248         """Returns the value the environment variable srctree had at the time
249         the Config instance was created, or None if srctree was not defined.
250         This variable points to the source directory and is used when building
251         in a separate directory."""
252         return self.srctree
253
254     def get_base_dir(self):
255         """Returns the base directory relative to which 'source' statements
256         will work, passed as an argument to Config.__init__()."""
257         return self.base_dir
258
259     def get_kconfig_filename(self):
260         """Returns the name of the (base) kconfig file this configuration was
261         loaded from."""
262         return self.filename
263
264     def get_config_filename(self):
265         """Returns the filename of the most recently loaded configuration file,
266         or None if no configuration has been loaded."""
267         return self.config_filename
268
269     def get_config_header(self):
270         """Returns the (uncommented) textual header of the .config file most
271         recently loaded with load_config(). Returns None if no .config file has
272         been loaded or if the most recently loaded .config file has no header.
273         The header consists of all lines up to but not including the first line
274         that either
275
276         1. Does not start with "#"
277         2. Has the form "# CONFIG_FOO is not set."
278         """
279         return self.config_header
280
281     def get_mainmenu_text(self):
282         """Returns the text of the 'mainmenu' statement (with $-references to
283         symbols replaced by symbol values), or None if the configuration has no
284         'mainmenu' statement."""
285         return None if self.mainmenu_text is None else \
286           self._expand_sym_refs(self.mainmenu_text)
287
288     def get_defconfig_filename(self):
289         """Returns the name of the defconfig file, which is the first existing
290         file in the list given in a symbol having 'option defconfig_list' set.
291         $-references to symbols will be expanded ("$FOO bar" -> "foo bar" if
292         FOO has the value "foo"). Returns None in case of no defconfig file.
293         Setting 'option defconfig_list' on multiple symbols currently results
294         in undefined behavior.
295
296         If the environment variable 'srctree' was set when the Config was
297         created, get_defconfig_filename() will first look relative to that
298         directory before looking in the current directory; see
299         Config.__init__().
300
301         WARNING: A wart here is that scripts/kconfig/Makefile sometimes uses
302         the --defconfig=<defconfig> option when calling the C implementation of
303         e.g. 'make defconfig'. This option overrides the 'option
304         defconfig_list' symbol, meaning the result from
305         get_defconfig_filename() might not match what 'make defconfig' would
306         use. That probably ought to be worked around somehow, so that this
307         function always gives the "expected" result."""
308         if self.defconfig_sym is None:
309             return None
310         for filename, cond_expr in self.defconfig_sym.def_exprs:
311             if self._eval_expr(cond_expr) == "y":
312                 filename = self._expand_sym_refs(filename)
313                 # We first look in $srctree. os.path.join() won't work here as
314                 # an absolute path in filename would override $srctree.
315                 srctree_filename = os.path.normpath(self.srctree + "/" +
316                                                     filename)
317                 if os.path.exists(srctree_filename):
318                     return srctree_filename
319                 if os.path.exists(filename):
320                     return filename
321         return None
322
323     def get_symbol(self, name):
324         """Returns the symbol with name 'name', or None if no such symbol
325         appears in the configuration. An alternative shorthand is conf[name],
326         where conf is a Config instance, though that will instead raise
327         KeyError if the symbol does not exist."""
328         return self.syms.get(name)
329
330     def __getitem__(self, name):
331         """Returns the symbol with name 'name'. Raises KeyError if the symbol
332         does not appear in the configuration."""
333         return self.syms[name]
334
335     def get_symbols(self, all_symbols=True):
336         """Returns a list of symbols from the configuration. An alternative for
337         iterating over all defined symbols (in the order of definition) is
338
339         for sym in config:
340             ...
341
342         which relies on Config implementing __iter__() and is equivalent to
343
344         for sym in config.get_symbols(False):
345             ...
346
347         all_symbols (default: True): If True, all symbols -- including special
348            and undefined symbols -- will be included in the result, in an
349            undefined order. If False, only symbols actually defined and not
350            merely referred to in the configuration will be included in the
351            result, and will appear in the order that they are defined within
352            the Kconfig configuration files."""
353         return list(self.syms.values()) if all_symbols else self.kconfig_syms
354
355     def __iter__(self):
356         """Convenience function for iterating over the set of all defined
357         symbols in the configuration, used like
358
359         for sym in conf:
360             ...
361
362         The iteration happens in the order of definition within the Kconfig
363         configuration files. Symbols only referred to but not defined will not
364         be included, nor will the special symbols n, m, and y. If you want to
365         include such symbols as well, see config.get_symbols()."""
366         return iter(self.kconfig_syms)
367
368     def get_choices(self):
369         """Returns a list containing all choice statements in the
370         configuration, in the order they appear in the Kconfig files."""
371         return self.choices
372
373     def get_menus(self):
374         """Returns a list containing all menus in the configuration, in the
375         order they appear in the Kconfig files."""
376         return self.menus
377
378     def get_comments(self):
379         """Returns a list containing all comments in the configuration, in the
380         order they appear in the Kconfig files."""
381         return self.comments
382
383     def get_top_level_items(self):
384         """Returns a list containing the items (symbols, menus, choices, and
385         comments) at the top level of the configuration -- that is, all items
386         that do not appear within a menu or choice. The items appear in the
387         same order as within the configuration."""
388         return self.top_block
389
390     def load_config(self, filename, replace=True):
391         """Loads symbol values from a file in the familiar .config format.
392         Equivalent to calling Symbol.set_user_value() to set each of the
393         values.
394
395         "# CONFIG_FOO is not set" within a .config file is treated specially
396         and sets the user value of FOO to 'n'. The C implementation works the
397         same way.
398
399         filename: The .config file to load. $-references to existing
400           environment variables will be expanded. For scripts to work even when
401           an alternative build directory is used with the Linux kernel, you
402           need to refer to the top-level kernel directory with "$srctree".
403
404         replace (default: True): True if the configuration should replace the
405            old configuration; False if it should add to it.
406
407         Returns a list or warnings (hopefully empty)
408         """
409
410         self._warnings = []
411         # Regular expressions for parsing .config files
412         _set_re_match = re.compile(r"{}(\w+)=(.*)".format(self.config_prefix)).match
413         _unset_re_match = re.compile(r"# {}(\w+) is not set".format(self.config_prefix)).match
414
415         # Put this first so that a missing file doesn't screw up our state
416         filename = os.path.expandvars(filename)
417         line_feeder = _FileFeed(filename)
418
419         self.config_filename = filename
420
421         #
422         # Read header
423         #
424
425         def is_header_line(line):
426             return line is not None and line.startswith("#") and \
427                    not _unset_re_match(line)
428
429         self.config_header = None
430
431         line = line_feeder.peek_next()
432         if is_header_line(line):
433             self.config_header = ""
434             while is_header_line(line_feeder.peek_next()):
435                 self.config_header += line_feeder.get_next()[1:]
436             # Remove trailing newline
437             if self.config_header.endswith("\n"):
438                 self.config_header = self.config_header[:-1]
439
440         #
441         # Read assignments. Hotspot for some workloads.
442         #
443
444         def warn_override(filename, linenr, name, old_user_val, new_user_val):
445             self._warn('overriding the value of {0}. '
446                        'Old value: "{1}", new value: "{2}".'
447                        .format(name, old_user_val, new_user_val),
448                        filename, linenr)
449
450         # Invalidate everything to keep things simple. It might be possible to
451         # improve performance for the case where multiple configurations are
452         # loaded by only invalidating a symbol (and its dependent symbols) if
453         # the new user value differs from the old. One complication would be
454         # that symbols not mentioned in the .config must lose their user value
455         # when replace = True, which is the usual case.
456         if replace:
457             self.unset_user_values()
458         else:
459             self._invalidate_all()
460
461         while 1:
462             line = line_feeder.get_next()
463             if line is None:
464                 return self._warnings
465
466             line = line.rstrip()
467
468             set_match = _set_re_match(line)
469             if set_match:
470                 name, val = set_match.groups()
471
472                 if val.startswith('"'):
473                     if len(val) < 2 or val[-1] != '"':
474                         _parse_error(line, "malformed string literal",
475                                      line_feeder.filename, line_feeder.linenr)
476                     # Strip quotes and remove escapings. The unescaping
477                     # procedure should be safe since " can only appear as \"
478                     # inside the string.
479                     val = val[1:-1].replace('\\"', '"').replace("\\\\", "\\")
480
481                 if name in self.syms:
482                     sym = self.syms[name]
483                     if sym.user_val is not None:
484                         warn_override(line_feeder.filename, line_feeder.linenr,
485                                       name, sym.user_val, val)
486
487                     if sym.is_choice_sym:
488                         user_mode = sym.parent.user_mode
489                         if user_mode is not None and user_mode != val:
490                             self._warn("assignment to {0} changes mode of "
491                                        'containing choice from "{1}" to "{2}".'
492                                        .format(name, val, user_mode),
493                                        line_feeder.filename,
494                                        line_feeder.linenr)
495
496                     sym._set_user_value_no_invalidate(val, True)
497                 else:
498                     if self.print_undef_assign:
499                         _stderr_msg('note: attempt to assign the value "{0}" '
500                                     "to the undefined symbol {1}."
501                                     .format(val, name),
502                                     line_feeder.filename, line_feeder.linenr)
503             else:
504                 unset_match = _unset_re_match(line)
505                 if unset_match:
506                     name = unset_match.group(1)
507                     if name in self.syms:
508                         sym = self.syms[name]
509                         if sym.user_val is not None:
510                             warn_override(line_feeder.filename,
511                                           line_feeder.linenr,
512                                           name, sym.user_val, "n")
513
514                         sym._set_user_value_no_invalidate("n", True)
515
516     def write_config(self, filename, header=None):
517         """Writes out symbol values in the familiar .config format.
518
519         Kconfiglib makes sure the format matches what the C implementation
520         would generate, down to whitespace. This eases testing.
521
522         filename: The filename under which to save the configuration.
523
524         header (default: None): A textual header that will appear at the
525            beginning of the file, with each line commented out automatically.
526            None means no header."""
527
528         for sym in self.syms_iter():
529             sym.already_written = False
530
531         with open(filename, "w") as f:
532             # Write header
533             if header is not None:
534                 f.write(_comment(header) + "\n")
535
536             # Build and write configuration
537             conf_strings = []
538             _make_block_conf(self.top_block, conf_strings.append)
539             f.write("\n".join(conf_strings) + "\n")
540
541     def eval(self, s):
542         """Returns the value of the expression 's' -- where 's' is represented
543         as a string -- in the context of the configuration. Raises
544         Kconfig_Syntax_Error if syntax errors are detected in 's'.
545
546         For example, if FOO and BAR are tristate symbols at least one of which
547         has the value "y", then config.eval("y && (FOO || BAR)") => "y"
548
549         This function always yields a tristate value. To get the value of
550         non-bool, non-tristate symbols, use Symbol.get_value().
551
552         The result of this function is consistent with how evaluation works for
553         conditional expressions in the configuration as well as in the C
554         implementation. "m" and m are rewritten as '"m" && MODULES' and 'm &&
555         MODULES', respectively, and a result of "m" will get promoted to "y" if
556         we're running without modules.
557
558         Syntax checking is somewhat lax, partly to be compatible with lax
559         parsing in the C implementation."""
560         return self._eval_expr(self._parse_expr(self._tokenize(s, True), # Feed
561                                                 None, # Current symbol/choice
562                                                 s))   # line
563
564     def unset_user_values(self):
565         """Resets the values of all symbols, as if Config.load_config() or
566         Symbol.set_user_value() had never been called."""
567         for sym in self.syms_iter():
568             sym._unset_user_value_no_recursive_invalidate()
569
570     def set_print_warnings(self, print_warnings):
571         """Determines whether warnings related to this configuration (for
572         things like attempting to assign illegal values to symbols with
573         Symbol.set_user_value()) should be printed to stderr.
574
575         print_warnings: True if warnings should be printed."""
576         self.print_warnings = print_warnings
577
578     def set_print_undef_assign(self, print_undef_assign):
579         """Determines whether informational messages related to assignments to
580         undefined symbols should be printed to stderr for this configuration.
581
582         print_undef_assign: If True, such messages will be printed."""
583         self.print_undef_assign = print_undef_assign
584
585     def __str__(self):
586         """Returns a string containing various information about the Config."""
587         return _lines("Configuration",
588                       "File                                   : " +
589                         self.filename,
590                       "Base directory                         : " +
591                         self.base_dir,
592                       "Value of $ARCH at creation time        : " +
593                         ("(not set)" if self.arch is None else self.arch),
594                       "Value of $SRCARCH at creation time     : " +
595                         ("(not set)" if self.srcarch is None else
596                                         self.srcarch),
597                       "Source tree (derived from $srctree;",
598                       "defaults to '.' if $srctree isn't set) : " +
599                         self.srctree,
600                       "Most recently loaded .config           : " +
601                         ("(no .config loaded)"
602                           if self.config_filename is None else
603                              self.config_filename),
604                       "Print warnings                         : " +
605                         BOOL_STR[self.print_warnings],
606                       "Print assignments to undefined symbols : " +
607                         BOOL_STR[self.print_undef_assign])
608
609     #
610     # Private methods
611     #
612
613     #
614     # Kconfig parsing
615     #
616
617     def _parse_file(self, filename, parent, deps, visible_if_deps, block):
618         """Parses the Kconfig file 'filename'. Appends the Items in the file
619         (and any file it sources) to the list passed in the 'block' parameter.
620         See _parse_block() for the meaning of the parameters."""
621         self._parse_block(_FileFeed(filename), None, parent, deps,
622                           visible_if_deps, block)
623
624     def _parse_block(self, line_feeder, end_marker, parent, deps,
625                      visible_if_deps, block):
626         """Parses a block, which is the contents of either a file or an if,
627         menu, or choice statement. Appends the Items to the list passed in the
628         'block' parameter.
629
630         line_feeder: A _FileFeed instance feeding lines from a file. The
631           Kconfig language is line-based in practice.
632
633         end_marker: The token that ends the block, e.g. T_ENDIF ("endif") for
634            ifs. None for files.
635
636         parent: The enclosing menu or choice, or None if we're at the top
637            level.
638
639         deps: Dependencies from enclosing menus, choices and ifs.
640
641         visible_if_deps (default: None): 'visible if' dependencies from
642            enclosing menus.
643
644         block: The list to add items to."""
645
646         while 1:
647             # Do we already have a tokenized line that we determined wasn't
648             # part of whatever we were parsing earlier? See comment in
649             # Config.__init__().
650             if self.end_line is not None:
651                 line = self.end_line
652                 tokens = self.end_line_tokens
653                 tokens.unget_all()
654
655                 self.end_line = None
656                 self.end_line_tokens = None
657             else:
658                 line = line_feeder.get_next()
659                 if line is None:
660                     if end_marker is not None:
661                         raise Kconfig_Syntax_Error("Unexpected end of file {0}"
662                                                  .format(line_feeder.filename))
663                     return
664
665                 tokens = self._tokenize(line, False, line_feeder.filename,
666                                         line_feeder.linenr)
667
668             t0 = tokens.get_next()
669             if t0 is None:
670                 continue
671
672             # Cases are ordered roughly by frequency, which speeds things up a
673             # bit
674
675             if t0 == T_CONFIG or t0 == T_MENUCONFIG:
676                 # The tokenizer will automatically allocate a new Symbol object
677                 # for any new names it encounters, so we don't need to worry
678                 # about that here.
679                 sym = tokens.get_next()
680
681                 # Symbols defined in multiple places get the parent of their
682                 # first definition. However, for symbols whose parents are
683                 # choice statements, the choice statement takes precedence.
684                 if not sym.is_defined_ or isinstance(parent, Choice):
685                     sym.parent = parent
686                 sym.is_defined_ = True
687
688                 self._parse_properties(line_feeder, sym, deps, visible_if_deps)
689
690                 self.kconfig_syms.append(sym)
691                 block.append(sym)
692
693             elif t0 == T_SOURCE:
694                 kconfig_file = tokens.get_next()
695                 exp_kconfig_file = self._expand_sym_refs(kconfig_file)
696                 f = os.path.join(self.base_dir, exp_kconfig_file)
697                 if not os.path.exists(f):
698                     raise IOError('{0}:{1}: sourced file "{2}" (expands to '
699                                   '"{3}") not found. Perhaps base_dir '
700                                   '(argument to Config.__init__(), currently '
701                                   '"{4}") is set to the wrong value.'
702                                   .format(line_feeder.filename,
703                                           line_feeder.linenr,
704                                           kconfig_file, exp_kconfig_file,
705                                           self.base_dir))
706                 # Add items to the same block
707                 self._parse_file(f, parent, deps, visible_if_deps, block)
708
709             elif t0 == end_marker:
710                 # We have reached the end of the block
711                 return
712
713             elif t0 == T_IF:
714                 # If statements are treated as syntactic sugar for adding
715                 # dependencies to enclosed items and do not have an explicit
716                 # object representation.
717
718                 dep_expr = self._parse_expr(tokens, None, line,
719                                             line_feeder.filename,
720                                             line_feeder.linenr)
721                 # Add items to the same block
722                 self._parse_block(line_feeder, T_ENDIF, parent,
723                                   _make_and(dep_expr, deps),
724                                   visible_if_deps, block)
725
726             elif t0 == T_COMMENT:
727                 comment = Comment()
728                 comment.config = self
729                 comment.parent = parent
730                 comment.filename = line_feeder.filename
731                 comment.linenr = line_feeder.linenr
732                 comment.text = tokens.get_next()
733
734                 self._parse_properties(line_feeder, comment, deps,
735                                        visible_if_deps)
736
737                 self.comments.append(comment)
738                 block.append(comment)
739
740             elif t0 == T_MENU:
741                 menu = Menu()
742                 menu.config = self
743                 menu.parent = parent
744                 menu.filename = line_feeder.filename
745                 menu.linenr = line_feeder.linenr
746                 menu.title = tokens.get_next()
747
748                 self._parse_properties(line_feeder, menu, deps,
749                                        visible_if_deps)
750
751                 # This needs to go before _parse_block() so that we get the
752                 # proper menu ordering in the case of nested functions
753                 self.menus.append(menu)
754                 # Parse contents and put Items in menu.block
755                 self._parse_block(line_feeder, T_ENDMENU, menu, menu.dep_expr,
756                                   _make_and(visible_if_deps,
757                                             menu.visible_if_expr),
758                                   menu.block)
759
760                 block.append(menu)
761
762             elif t0 == T_CHOICE:
763                 name = tokens.get_next()
764                 if name is None:
765                     choice = Choice()
766                     self.choices.append(choice)
767                 else:
768                     # Named choice
769                     choice = self.named_choices.get(name)
770                     if choice is None:
771                         choice = Choice()
772                         choice.name = name
773                         self.named_choices[name] = choice
774                         self.choices.append(choice)
775
776                 choice.config = self
777                 choice.parent = parent
778
779                 choice.def_locations.append((line_feeder.filename,
780                                              line_feeder.linenr))
781
782                 self._parse_properties(line_feeder, choice, deps,
783                                        visible_if_deps)
784
785                 # Parse contents and put Items in choice.block
786                 self._parse_block(line_feeder, T_ENDCHOICE, choice, deps,
787                                   visible_if_deps, choice.block)
788
789                 choice._determine_actual_symbols()
790
791                 # If no type is specified for the choice, its type is that of
792                 # the first choice item with a specified type
793                 if choice.type == UNKNOWN:
794                     for item in choice.actual_symbols:
795                         if item.type != UNKNOWN:
796                             choice.type = item.type
797                             break
798
799                 # Each choice item of UNKNOWN type gets the type of the choice
800                 for item in choice.actual_symbols:
801                     if item.type == UNKNOWN:
802                         item.type = choice.type
803
804                 block.append(choice)
805
806             elif t0 == T_MAINMENU:
807                 text = tokens.get_next()
808                 if self.mainmenu_text is not None:
809                     self._warn("overriding 'mainmenu' text. "
810                                'Old value: "{0}", new value: "{1}".'
811                                .format(self.mainmenu_text, text),
812                                line_feeder.filename, line_feeder.linenr)
813                 self.mainmenu_text = text
814
815             else:
816                 _parse_error(line, "unrecognized construct",
817                              line_feeder.filename, line_feeder.linenr)
818
819     def _parse_properties(self, line_feeder, stmt, deps, visible_if_deps):
820         """Parsing of properties for symbols, menus, choices, and comments.
821         Takes care of propagating dependencies from enclosing menus and ifs."""
822
823         def parse_val_and_cond(tokens, line, filename, linenr):
824             """Parses '<expr1> if <expr2>' constructs, where the 'if' part is
825             optional. Returns a tuple containing the parsed expressions, with
826             None as the second element if the 'if' part is missing."""
827             return (self._parse_expr(tokens, stmt, line, filename, linenr,
828                                      False),
829                     self._parse_expr(tokens, stmt, line, filename, linenr)
830                     if tokens.check(T_IF) else None)
831
832         # In case the symbol is defined in multiple locations, we need to
833         # remember what prompts, defaults, selects, and implies are new for
834         # this definition, as "depends on" should only apply to the local
835         # definition.
836         new_prompt = None
837         new_def_exprs = []
838         new_selects = []
839         new_implies = []
840
841         # Dependencies from 'depends on' statements
842         depends_on_expr = None
843
844         while 1:
845             line = line_feeder.get_next()
846             if line is None:
847                 break
848
849             filename = line_feeder.filename
850             linenr = line_feeder.linenr
851
852             tokens = self._tokenize(line, False, filename, linenr)
853
854             t0 = tokens.get_next()
855             if t0 is None:
856                 continue
857
858             # Cases are ordered roughly by frequency, which speeds things up a
859             # bit
860
861             if t0 == T_DEPENDS:
862                 if not tokens.check(T_ON):
863                     _parse_error(line, 'expected "on" after "depends"',
864                                  filename, linenr)
865
866                 parsed_deps = self._parse_expr(tokens, stmt, line, filename,
867                                                linenr)
868
869                 if isinstance(stmt, (Menu, Comment)):
870                     stmt.orig_deps = _make_and(stmt.orig_deps, parsed_deps)
871                 else:
872                     depends_on_expr = _make_and(depends_on_expr, parsed_deps)
873
874             elif t0 == T_HELP:
875                 # Find first non-blank (not all-space) line and get its
876                 # indentation
877                 line = line_feeder.next_nonblank()
878                 if line is None:
879                     stmt.help = ""
880                     break
881                 indent = _indentation(line)
882                 if indent == 0:
883                     # If the first non-empty lines has zero indent, there is no
884                     # help text
885                     stmt.help = ""
886                     line_feeder.unget()
887                     break
888
889                 # The help text goes on till the first non-empty line with less
890                 # indent
891                 help_lines = [_deindent(line, indent)]
892                 while 1:
893                     line = line_feeder.get_next()
894                     if line is None or \
895                        (not line.isspace() and _indentation(line) < indent):
896                         stmt.help = "".join(help_lines)
897                         break
898                     help_lines.append(_deindent(line, indent))
899
900                 if line is None:
901                     break
902
903                 line_feeder.unget()
904
905             elif t0 == T_SELECT:
906                 target = tokens.get_next()
907
908                 stmt.referenced_syms.add(target)
909                 stmt.selected_syms.add(target)
910
911                 new_selects.append(
912                     (target,
913                      self._parse_expr(tokens, stmt, line, filename, linenr)
914                      if tokens.check(T_IF) else None))
915
916             elif t0 == T_IMPLY:
917                 target = tokens.get_next()
918
919                 stmt.referenced_syms.add(target)
920                 stmt.implied_syms.add(target)
921
922                 new_implies.append(
923                     (target,
924                      self._parse_expr(tokens, stmt, line, filename, linenr)
925                      if tokens.check(T_IF) else None))
926
927             elif t0 in (T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING):
928                 stmt.type = TOKEN_TO_TYPE[t0]
929                 if tokens.peek_next() is not None:
930                     new_prompt = parse_val_and_cond(tokens, line, filename,
931                                                     linenr)
932
933             elif t0 == T_DEFAULT:
934                 new_def_exprs.append(parse_val_and_cond(tokens, line, filename,
935                                                         linenr))
936
937             elif t0 == T_DEF_BOOL:
938                 stmt.type = BOOL
939                 if tokens.peek_next() is not None:
940                     new_def_exprs.append(parse_val_and_cond(tokens, line,
941                                                             filename, linenr))
942
943             elif t0 == T_PROMPT:
944                 # 'prompt' properties override each other within a single
945                 # definition of a symbol, but additional prompts can be added
946                 # by defining the symbol multiple times; hence 'new_prompt'
947                 # instead of 'prompt'.
948                 new_prompt = parse_val_and_cond(tokens, line, filename, linenr)
949
950             elif t0 == T_RANGE:
951                 low = tokens.get_next()
952                 high = tokens.get_next()
953                 stmt.referenced_syms.add(low)
954                 stmt.referenced_syms.add(high)
955
956                 stmt.ranges.append(
957                     (low, high,
958                      self._parse_expr(tokens, stmt, line, filename, linenr)
959                      if tokens.check(T_IF) else None))
960
961             elif t0 == T_DEF_TRISTATE:
962                 stmt.type = TRISTATE
963                 if tokens.peek_next() is not None:
964                     new_def_exprs.append(parse_val_and_cond(tokens, line,
965                                                             filename, linenr))
966
967             elif t0 == T_OPTION:
968                 if tokens.check(T_ENV) and tokens.check(T_EQUAL):
969                     env_var = tokens.get_next()
970
971                     stmt.is_special_ = True
972                     stmt.is_from_env = True
973
974                     if env_var not in os.environ:
975                         self._warn("The symbol {0} references the "
976                                    "non-existent environment variable {1} and "
977                                    "will get the empty string as its value. "
978                                    "If you're using Kconfiglib via "
979                                    "'make (i)scriptconfig', it should have "
980                                    "set up the environment correctly for you. "
981                                    "If you still got this message, that "
982                                    "might be an error, and you should email "
983                                    "ulfalizer a.t Google's email service."""
984                                    .format(stmt.name, env_var),
985                                    filename, linenr)
986
987                         stmt.cached_val = ""
988                     else:
989                         stmt.cached_val = os.environ[env_var]
990
991                 elif tokens.check(T_DEFCONFIG_LIST):
992                     self.defconfig_sym = stmt
993
994                 elif tokens.check(T_MODULES):
995                     # To reduce warning spam, only warn if 'option modules' is
996                     # set on some symbol that isn't MODULES, which should be
997                     # safe. I haven't run into any projects that make use
998                     # modules besides the kernel yet, and there it's likely to
999                     # keep being called "MODULES".
1000                     if stmt.name != "MODULES":
1001                         self._warn("the 'modules' option is not supported. "
1002                                    "Let me know if this is a problem for you; "
1003                                    "it shouldn't be that hard to implement. "
1004                                    "(Note that modules are still supported -- "
1005                                    "Kconfiglib just assumes the symbol name "
1006                                    "MODULES, like older versions of the C "
1007                                    "implementation did when 'option modules' "
1008                                    "wasn't used.)",
1009                                    filename, linenr)
1010
1011                 elif tokens.check(T_ALLNOCONFIG_Y):
1012                     if not isinstance(stmt, Symbol):
1013                         _parse_error(line,
1014                                      "the 'allnoconfig_y' option is only "
1015                                      "valid for symbols",
1016                                      filename, linenr)
1017                     stmt.allnoconfig_y = True
1018
1019                 else:
1020                     _parse_error(line, "unrecognized option", filename, linenr)
1021
1022             elif t0 == T_VISIBLE:
1023                 if not tokens.check(T_IF):
1024                     _parse_error(line, 'expected "if" after "visible"',
1025                                  filename, linenr)
1026                 if not isinstance(stmt, Menu):
1027                     _parse_error(line,
1028                                  "'visible if' is only valid for menus",
1029                                  filename, linenr)
1030
1031                 parsed_deps = self._parse_expr(tokens, stmt, line, filename,
1032                                                linenr)
1033                 stmt.visible_if_expr = _make_and(stmt.visible_if_expr,
1034                                                  parsed_deps)
1035
1036             elif t0 == T_OPTIONAL:
1037                 if not isinstance(stmt, Choice):
1038                     _parse_error(line,
1039                                  '"optional" is only valid for choices',
1040                                  filename,
1041                                  linenr)
1042                 stmt.optional = True
1043
1044             else:
1045                 # See comment in Config.__init__()
1046                 self.end_line = line
1047                 self.end_line_tokens = tokens
1048                 break
1049
1050         # Done parsing properties. Now propagate 'depends on' and enclosing
1051         # menu/if dependencies to expressions.
1052
1053         # The set of symbols referenced directly by the statement plus all
1054         # symbols referenced by enclosing menus and ifs
1055         stmt.all_referenced_syms = stmt.referenced_syms | _get_expr_syms(deps)
1056
1057         # Save original dependencies from enclosing menus and ifs
1058         stmt.deps_from_containing = deps
1059
1060         if isinstance(stmt, (Menu, Comment)):
1061             stmt.dep_expr = _make_and(stmt.orig_deps, deps)
1062         else:
1063             # Symbol or Choice
1064
1065             # See comment for 'menu_dep'
1066             stmt.menu_dep = _make_and(deps, depends_on_expr)
1067
1068             # Propagate dependencies to prompts
1069
1070             if new_prompt is not None:
1071                 prompt, cond_expr = new_prompt
1072                 # Propagate 'visible if' dependencies from menus and local
1073                 # 'depends on' dependencies
1074                 cond_expr = _make_and(_make_and(cond_expr, visible_if_deps),
1075                                       depends_on_expr)
1076                 # Save original
1077                 stmt.orig_prompts.append((prompt, cond_expr))
1078                 # Finalize with dependencies from enclosing menus and ifs
1079                 stmt.prompts.append((prompt, _make_and(cond_expr, deps)))
1080
1081             # Propagate dependencies to defaults
1082
1083             # Propagate 'depends on' dependencies
1084             new_def_exprs = [(val_expr, _make_and(cond_expr, depends_on_expr))
1085                              for val_expr, cond_expr in new_def_exprs]
1086             # Save original
1087             stmt.orig_def_exprs.extend(new_def_exprs)
1088             # Finalize with dependencies from enclosing menus and ifs
1089             stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
1090                                    for val_expr, cond_expr in new_def_exprs])
1091
1092             # Propagate dependencies to selects and implies
1093
1094             # Only symbols can select and imply
1095             if isinstance(stmt, Symbol):
1096                 # Propagate 'depends on' dependencies
1097                 new_selects = [(target, _make_and(cond_expr, depends_on_expr))
1098                                for target, cond_expr in new_selects]
1099                 new_implies = [(target, _make_and(cond_expr, depends_on_expr))
1100                                for target, cond_expr in new_implies]
1101                 # Save original
1102                 stmt.orig_selects.extend(new_selects)
1103                 stmt.orig_implies.extend(new_implies)
1104                 # Finalize with dependencies from enclosing menus and ifs
1105                 for target, cond in new_selects:
1106                     target.rev_dep = \
1107                         _make_or(target.rev_dep,
1108                                  _make_and(stmt, _make_and(cond, deps)))
1109                 for target, cond in new_implies:
1110                     target.weak_rev_dep = \
1111                         _make_or(target.weak_rev_dep,
1112                                  _make_and(stmt, _make_and(cond, deps)))
1113
1114     def _parse_expr(self, feed, cur_item, line, filename=None, linenr=None,
1115                     transform_m=True):
1116         """Parses an expression from the tokens in 'feed' using a simple
1117         top-down approach. The result has the form
1118         '(<operator>, [<parsed operands>])', where <operator> is e.g.
1119         kconfiglib.AND. If there is only one operand (i.e., no && or ||), then
1120         the operand is returned directly. This also goes for subexpressions.
1121
1122         feed: _Feed instance containing the tokens for the expression.
1123
1124         cur_item: The item (Symbol, Choice, Menu, or Comment) currently being
1125            parsed, or None if we're not parsing an item. Used for recording
1126            references to symbols.
1127
1128         line: The line containing the expression being parsed.
1129
1130         filename (default: None): The file containing the expression.
1131
1132         linenr (default: None): The line number containing the expression.
1133
1134         transform_m (default: False): Determines if 'm' should be rewritten to
1135            'm && MODULES' -- see parse_val_and_cond().
1136
1137         Expression grammar, in decreasing order of precedence:
1138
1139         <expr> -> <symbol>
1140                   <symbol> '=' <symbol>
1141                   <symbol> '!=' <symbol>
1142                   '(' <expr> ')'
1143                   '!' <expr>
1144                   <expr> '&&' <expr>
1145                   <expr> '||' <expr>"""
1146
1147         # Use instance variables to avoid having to pass these as arguments
1148         # through the top-down parser in _parse_expr_rec(), which is tedious
1149         # and obfuscates the code. A profiler run shows no noticeable
1150         # performance difference.
1151         self._cur_item = cur_item
1152         self._transform_m = transform_m
1153         self._line = line
1154         self._filename = filename
1155         self._linenr = linenr
1156
1157         return self._parse_expr_rec(feed)
1158
1159     def _parse_expr_rec(self, feed):
1160         or_term = self._parse_or_term(feed)
1161         if not feed.check(T_OR):
1162             # Common case -- no need for an OR node since it's just a single
1163             # operand
1164             return or_term
1165         or_terms = [or_term, self._parse_or_term(feed)]
1166         while feed.check(T_OR):
1167             or_terms.append(self._parse_or_term(feed))
1168         return (OR, or_terms)
1169
1170     def _parse_or_term(self, feed):
1171         and_term = self._parse_factor(feed)
1172         if not feed.check(T_AND):
1173             # Common case -- no need for an AND node since it's just a single
1174             # operand
1175             return and_term
1176         and_terms = [and_term, self._parse_factor(feed)]
1177         while feed.check(T_AND):
1178             and_terms.append(self._parse_factor(feed))
1179         return (AND, and_terms)
1180
1181     def _parse_factor(self, feed):
1182         token = feed.get_next()
1183
1184         if isinstance(token, (Symbol, str)):
1185             if self._cur_item is not None and isinstance(token, Symbol):
1186                 self._cur_item.referenced_syms.add(token)
1187
1188             next_token = feed.peek_next()
1189             # For conditional expressions ('depends on <expr>',
1190             # '... if <expr>', # etc.), "m" and m are rewritten to
1191             # "m" && MODULES.
1192             if next_token != T_EQUAL and next_token != T_UNEQUAL:
1193                 if self._transform_m and (token is self.m or token == "m"):
1194                     return (AND, ["m", self._sym_lookup("MODULES")])
1195                 return token
1196
1197             relation = EQUAL if (feed.get_next() == T_EQUAL) else UNEQUAL
1198             token_2 = feed.get_next()
1199             if self._cur_item is not None and isinstance(token_2, Symbol):
1200                 self._cur_item.referenced_syms.add(token_2)
1201             return (relation, token, token_2)
1202
1203         if token == T_NOT:
1204             return (NOT, self._parse_factor(feed))
1205
1206         if token == T_OPEN_PAREN:
1207             expr_parse = self._parse_expr_rec(feed)
1208             if not feed.check(T_CLOSE_PAREN):
1209                 _parse_error(self._line, "missing end parenthesis",
1210                              self._filename, self._linenr)
1211             return expr_parse
1212
1213         _parse_error(self._line, "malformed expression", self._filename,
1214                      self._linenr)
1215
1216     def _tokenize(self, s, for_eval, filename=None, linenr=None):
1217         """Returns a _Feed instance containing tokens derived from the string
1218         's'. Registers any new symbols encountered (via _sym_lookup()).
1219
1220         (I experimented with a pure regular expression implementation, but it
1221         came out slower, less readable, and wouldn't have been as flexible.)
1222
1223         for_eval: True when parsing an expression for a call to Config.eval(),
1224            in which case we should not treat the first token specially nor
1225            register new symbols."""
1226
1227         s = s.strip()
1228         if s == "" or s[0] == "#":
1229             return _Feed([])
1230
1231         if for_eval:
1232             previous = None # The previous token seen
1233             tokens = []
1234             i = 0 # The current index in the string being tokenized
1235
1236         else:
1237             # The initial word on a line is parsed specially. Let
1238             # command_chars = [A-Za-z0-9_]. Then
1239             #  - leading non-command_chars characters are ignored, and
1240             #  - the first token consists the following one or more
1241             #    command_chars characters.
1242             # This is why things like "----help--" are accepted.
1243             initial_token_match = _initial_token_re_match(s)
1244             if initial_token_match is None:
1245                 return _Feed([])
1246             keyword = _get_keyword(initial_token_match.group(1))
1247             if keyword == T_HELP:
1248                 # Avoid junk after "help", e.g. "---", being registered as a
1249                 # symbol
1250                 return _Feed([T_HELP])
1251             if keyword is None:
1252                 # We expect a keyword as the first token
1253                 _tokenization_error(s, filename, linenr)
1254
1255             previous = keyword
1256             tokens = [keyword]
1257             # The current index in the string being tokenized
1258             i = initial_token_match.end()
1259
1260         # _tokenize() is a hotspot during parsing, and this speeds things up a
1261         # bit
1262         strlen = len(s)
1263         append = tokens.append
1264
1265         # Main tokenization loop. (Handles tokens past the first one.)
1266         while i < strlen:
1267             # Test for an identifier/keyword preceded by whitespace first; this
1268             # is the most common case.
1269             id_keyword_match = _id_keyword_re_match(s, i)
1270             if id_keyword_match:
1271                 # We have an identifier or keyword. The above also stripped any
1272                 # whitespace for us.
1273                 name = id_keyword_match.group(1)
1274                 # Jump past it
1275                 i = id_keyword_match.end()
1276
1277                 keyword = _get_keyword(name)
1278                 if keyword is not None:
1279                     # It's a keyword
1280                     append(keyword)
1281                 elif previous in STRING_LEX:
1282                     # What would ordinarily be considered an identifier is
1283                     # treated as a string after certain tokens
1284                     append(name)
1285                 else:
1286                     # It's a symbol name. _sym_lookup() will take care of
1287                     # allocating a new Symbol instance if it's the first time
1288                     # we see it.
1289                     sym = self._sym_lookup(name, for_eval)
1290
1291                     if previous == T_CONFIG or previous == T_MENUCONFIG:
1292                         # If the previous token is T_(MENU)CONFIG
1293                         # ("(menu)config"), we're tokenizing the first line of
1294                         # a symbol definition, and should remember this as a
1295                         # location where the symbol is defined
1296                         sym.def_locations.append((filename, linenr))
1297                     else:
1298                         # Otherwise, it's a reference to the symbol
1299                         sym.ref_locations.append((filename, linenr))
1300
1301                     append(sym)
1302
1303             else:
1304                 # Not an identifier/keyword
1305
1306                 while i < strlen and s[i].isspace():
1307                     i += 1
1308                 if i == strlen:
1309                     break
1310                 c = s[i]
1311                 i += 1
1312
1313                 # String literal (constant symbol)
1314                 if c == '"' or c == "'":
1315                     if "\\" in s:
1316                         # Slow path: This could probably be sped up, but it's a
1317                         # very unusual case anyway.
1318                         quote = c
1319                         val = ""
1320                         while 1:
1321                             if i >= len(s):
1322                                 _tokenization_error(s, filename, linenr)
1323                             c = s[i]
1324                             if c == quote:
1325                                 break
1326                             if c == "\\":
1327                                 if i + 1 >= len(s):
1328                                     _tokenization_error(s, filename, linenr)
1329                                 val += s[i + 1]
1330                                 i += 2
1331                             else:
1332                                 val += c
1333                                 i += 1
1334                         i += 1
1335                         append(val)
1336                     else:
1337                         # Fast path: If the string contains no backslashes
1338                         # (almost always) we can simply look for the matching
1339                         # quote.
1340                         end = s.find(c, i)
1341                         if end == -1:
1342                             _tokenization_error(s, filename, linenr)
1343                         append(s[i:end])
1344                         i = end + 1
1345
1346                 elif c == "&":
1347                     # Invalid characters are ignored
1348                     if i >= len(s) or s[i] != "&": continue
1349                     append(T_AND)
1350                     i += 1
1351
1352                 elif c == "|":
1353                     # Invalid characters are ignored
1354                     if i >= len(s) or s[i] != "|": continue
1355                     append(T_OR)
1356                     i += 1
1357
1358                 elif c == "!":
1359                     if i < len(s) and s[i] == "=":
1360                         append(T_UNEQUAL)
1361                         i += 1
1362                     else:
1363                         append(T_NOT)
1364
1365                 elif c == "=": append(T_EQUAL)
1366                 elif c == "(": append(T_OPEN_PAREN)
1367                 elif c == ")": append(T_CLOSE_PAREN)
1368                 elif c == "#": break # Comment
1369
1370                 else: continue # Invalid characters are ignored
1371
1372             previous = tokens[-1]
1373
1374         return _Feed(tokens)
1375
1376     def _sym_lookup(self, name, for_eval=False):
1377         """Fetches the symbol 'name' from the symbol table, creating and
1378         registering it if it does not exist. If 'for_eval' is True, the symbol
1379         won't be added to the symbol table if it does not exist -- this is for
1380         Config.eval()."""
1381         if name in self.syms:
1382             return self.syms[name]
1383
1384         new_sym = Symbol()
1385         new_sym.config = self
1386         new_sym.name = name
1387         if for_eval:
1388             self._warn("no symbol {0} in configuration".format(name))
1389         else:
1390             self.syms[name] = new_sym
1391         return new_sym
1392
1393     #
1394     # Expression evaluation
1395     #
1396
1397     def _eval_expr(self, expr):
1398         """Evaluates an expression to "n", "m", or "y"."""
1399
1400         # Handles e.g. an "x if y" condition where the "if y" part is missing.
1401         if expr is None:
1402             return "y"
1403
1404         res = self._eval_expr_rec(expr)
1405         if res == "m":
1406             # Promote "m" to "y" if we're running without modules.
1407             #
1408             # Internally, "m" is often rewritten to "m" && MODULES by both the
1409             # C implementation and Kconfiglib, which takes care of cases where
1410             # "m" should be demoted to "n" instead.
1411             modules_sym = self.syms.get("MODULES")
1412             if modules_sym is None or modules_sym.get_value() != "y":
1413                 return "y"
1414         return res
1415
1416     def _eval_expr_rec(self, expr):
1417         if isinstance(expr, Symbol):
1418             # Non-bool/tristate symbols are always "n" in a tristate sense,
1419             # regardless of their value
1420             if expr.type != BOOL and expr.type != TRISTATE:
1421                 return "n"
1422             return expr.get_value()
1423
1424         if isinstance(expr, str):
1425             return expr if (expr == "y" or expr == "m") else "n"
1426
1427         # Ordered by frequency
1428
1429         if expr[0] == AND:
1430             res = "y"
1431             for subexpr in expr[1]:
1432                 ev = self._eval_expr_rec(subexpr)
1433                 # Return immediately upon discovering an "n" term
1434                 if ev == "n":
1435                     return "n"
1436                 if ev == "m":
1437                     res = "m"
1438             # 'res' is either "m" or "y" here; we already handled the
1439             # short-circuiting "n" case in the loop.
1440             return res
1441
1442         if expr[0] == NOT:
1443             ev = self._eval_expr_rec(expr[1])
1444             if ev == "y":
1445                 return "n"
1446             return "y" if (ev == "n") else "m"
1447
1448         if expr[0] == OR:
1449             res = "n"
1450             for subexpr in expr[1]:
1451                 ev = self._eval_expr_rec(subexpr)
1452                 # Return immediately upon discovering a "y" term
1453                 if ev == "y":
1454                     return "y"
1455                 if ev == "m":
1456                     res = "m"
1457             # 'res' is either "n" or "m" here; we already handled the
1458             # short-circuiting "y" case in the loop.
1459             return res
1460
1461         if expr[0] == EQUAL:
1462             return "y" if (_str_val(expr[1]) == _str_val(expr[2])) else "n"
1463
1464         if expr[0] == UNEQUAL:
1465             return "y" if (_str_val(expr[1]) != _str_val(expr[2])) else "n"
1466
1467         _internal_error("Internal error while evaluating expression: "
1468                         "unknown operation {0}.".format(expr[0]))
1469
1470     def _eval_min(self, e1, e2):
1471         """Returns the minimum value of the two expressions. Equates None with
1472         'y'."""
1473         e1_eval = self._eval_expr(e1)
1474         e2_eval = self._eval_expr(e2)
1475         return e1_eval if tri_less(e1_eval, e2_eval) else e2_eval
1476
1477     def _eval_max(self, e1, e2):
1478         """Returns the maximum value of the two expressions. Equates None with
1479         'y'."""
1480         e1_eval = self._eval_expr(e1)
1481         e2_eval = self._eval_expr(e2)
1482         return e1_eval if tri_greater(e1_eval, e2_eval) else e2_eval
1483
1484     #
1485     # Dependency tracking (for caching and invalidation)
1486     #
1487
1488     def _build_dep(self):
1489         """Populates the Symbol.dep sets, linking the symbol to the symbols
1490         that immediately depend on it in the sense that changing the value of
1491         the symbol might affect the values of those other symbols. This is used
1492         for caching/invalidation purposes. The calculated sets might be larger
1493         than necessary as we don't do any complicated analysis of the
1494         expressions."""
1495
1496         # Adds 'sym' as a directly dependent symbol to all symbols that appear
1497         # in the expression 'e'
1498         def add_expr_deps(e, sym):
1499             for s in _get_expr_syms(e):
1500                 s.dep.add(sym)
1501
1502         # The directly dependent symbols of a symbol are:
1503         #  - Any symbols whose prompts, default values, rev_dep (select
1504         #    condition), weak_rev_dep (imply condition) or ranges depend on the
1505         #    symbol
1506         #  - Any symbols that belong to the same choice statement as the symbol
1507         #    (these won't be included in 'dep' as that makes the dependency
1508         #    graph unwieldy, but Symbol._get_dependent() will include them)
1509         #  - Any symbols in a choice statement that depends on the symbol
1510         for sym in self.syms_iter():
1511             for _, e in sym.prompts:
1512                 add_expr_deps(e, sym)
1513
1514             for v, e in sym.def_exprs:
1515                 add_expr_deps(v, sym)
1516                 add_expr_deps(e, sym)
1517
1518             add_expr_deps(sym.rev_dep, sym)
1519             add_expr_deps(sym.weak_rev_dep, sym)
1520
1521             for l, u, e in sym.ranges:
1522                 add_expr_deps(l, sym)
1523                 add_expr_deps(u, sym)
1524                 add_expr_deps(e, sym)
1525
1526             if sym.is_choice_sym:
1527                 choice = sym.parent
1528                 for _, e in choice.prompts:
1529                     add_expr_deps(e, sym)
1530                 for _, e in choice.def_exprs:
1531                     add_expr_deps(e, sym)
1532
1533     def _eq_to_sym(self, eq):
1534         """_expr_depends_on() helper. For (in)equalities of the form sym = y/m
1535         or sym != n, returns sym. For other (in)equalities, returns None."""
1536         relation, left, right = eq
1537
1538         def transform_y_m_n(item):
1539             if item is self.y: return "y"
1540             if item is self.m: return "m"
1541             if item is self.n: return "n"
1542             return item
1543
1544         left = transform_y_m_n(left)
1545         right = transform_y_m_n(right)
1546
1547         # Make sure the symbol (if any) appears to the left
1548         if not isinstance(left, Symbol):
1549             left, right = right, left
1550         if not isinstance(left, Symbol):
1551             return None
1552         if (relation == EQUAL and (right == "y" or right == "m")) or \
1553            (relation == UNEQUAL and right == "n"):
1554             return left
1555         return None
1556
1557     def _expr_depends_on(self, expr, sym):
1558         """Reimplementation of expr_depends_symbol() from mconf.c. Used to
1559         determine if a submenu should be implicitly created, which influences
1560         what items inside choice statements are considered choice items."""
1561         if expr is None:
1562             return False
1563
1564         def rec(expr):
1565             if isinstance(expr, str):
1566                 return False
1567             if isinstance(expr, Symbol):
1568                 return expr is sym
1569
1570             if expr[0] in (EQUAL, UNEQUAL):
1571                 return self._eq_to_sym(expr) is sym
1572             if expr[0] == AND:
1573                 for and_expr in expr[1]:
1574                     if rec(and_expr):
1575                         return True
1576             return False
1577
1578         return rec(expr)
1579
1580     def _invalidate_all(self):
1581         for sym in self.syms_iter():
1582             sym._invalidate()
1583
1584     #
1585     # Printing and misc.
1586     #
1587
1588     def _expand_sym_refs(self, s):
1589         """Expands $-references to symbols in 's' to symbol values, or to the
1590         empty string for undefined symbols."""
1591
1592         while 1:
1593             sym_ref_match = _sym_ref_re_search(s)
1594             if sym_ref_match is None:
1595                 return s
1596
1597             sym_name = sym_ref_match.group(0)[1:]
1598             sym = self.syms.get(sym_name)
1599             expansion = "" if sym is None else sym.get_value()
1600
1601             s = s[:sym_ref_match.start()] + \
1602                 expansion + \
1603                 s[sym_ref_match.end():]
1604
1605     def _expr_val_str(self, expr, no_value_str="(none)",
1606                       get_val_instead_of_eval=False):
1607         """Printing helper. Returns a string with 'expr' and its value.
1608
1609         no_value_str: String to return when 'expr' is missing (None).
1610
1611         get_val_instead_of_eval: Assume 'expr' is a symbol or string (constant
1612           symbol) and get its value directly instead of evaluating it to a
1613           tristate value."""
1614
1615         if expr is None:
1616             return no_value_str
1617
1618         if get_val_instead_of_eval:
1619             if isinstance(expr, str):
1620                 return _expr_to_str(expr)
1621             val = expr.get_value()
1622         else:
1623             val = self._eval_expr(expr)
1624
1625         return "{0} (value: {1})".format(_expr_to_str(expr), _expr_to_str(val))
1626
1627     def _get_sym_or_choice_str(self, sc):
1628         """Symbols and choices have many properties in common, so we factor out
1629         common __str__() stuff here. "sc" is short for "symbol or choice"."""
1630
1631         # As we deal a lot with string representations here, use some
1632         # convenient shorthand:
1633         s = _expr_to_str
1634
1635         #
1636         # Common symbol/choice properties
1637         #
1638
1639         user_val_str = "(no user value)" if sc.user_val is None else \
1640                        s(sc.user_val)
1641
1642         # Build prompts string
1643         if not sc.prompts:
1644             prompts_str = " (no prompts)"
1645         else:
1646             prompts_str_rows = []
1647             for prompt, cond_expr in sc.orig_prompts:
1648                 prompts_str_rows.append(
1649                     ' "{0}"'.format(prompt) if cond_expr is None else
1650                     ' "{0}" if {1}'.format(prompt,
1651                                            self._expr_val_str(cond_expr)))
1652             prompts_str = "\n".join(prompts_str_rows)
1653
1654         # Build locations string
1655         locations_str = "(no locations)" if not sc.def_locations else \
1656                         " ".join(["{0}:{1}".format(filename, linenr) for
1657                                   filename, linenr in sc.def_locations])
1658
1659         # Build additional-dependencies-from-menus-and-ifs string
1660         additional_deps_str = " " + \
1661           self._expr_val_str(sc.deps_from_containing,
1662                              "(no additional dependencies)")
1663
1664         #
1665         # Symbol-specific stuff
1666         #
1667
1668         if isinstance(sc, Symbol):
1669             # Build ranges string
1670             if isinstance(sc, Symbol):
1671                 if not sc.ranges:
1672                     ranges_str = " (no ranges)"
1673                 else:
1674                     ranges_str_rows = []
1675                     for l, u, cond_expr in sc.ranges:
1676                         ranges_str_rows.append(
1677                             " [{0}, {1}]".format(s(l), s(u))
1678                             if cond_expr is None else
1679                             " [{0}, {1}] if {2}"
1680                             .format(s(l), s(u), self._expr_val_str(cond_expr)))
1681                     ranges_str = "\n".join(ranges_str_rows)
1682
1683             # Build default values string
1684             if not sc.def_exprs:
1685                 defaults_str = " (no default values)"
1686             else:
1687                 defaults_str_rows = []
1688                 for val_expr, cond_expr in sc.orig_def_exprs:
1689                     row_str = " " + self._expr_val_str(val_expr, "(none)",
1690                                                        sc.type == STRING)
1691                     defaults_str_rows.append(row_str)
1692                     defaults_str_rows.append("  Condition: " +
1693                                                self._expr_val_str(cond_expr))
1694                 defaults_str = "\n".join(defaults_str_rows)
1695
1696             # Build selects string
1697             if not sc.orig_selects:
1698                 selects_str = " (no selects)"
1699             else:
1700                 selects_str_rows = []
1701                 for target, cond_expr in sc.orig_selects:
1702                     selects_str_rows.append(
1703                         " {0}".format(target.name) if cond_expr is None else
1704                         " {0} if {1}".format(target.name,
1705                                              self._expr_val_str(cond_expr)))
1706                 selects_str = "\n".join(selects_str_rows)
1707
1708             # Build implies string
1709             if not sc.orig_implies:
1710                 implies_str = " (no implies)"
1711             else:
1712                 implies_str_rows = []
1713                 for target, cond_expr in sc.orig_implies:
1714                     implies_str_rows.append(
1715                         " {0}".format(target.name) if cond_expr is None else
1716                         " {0} if {1}".format(target.name,
1717                                              self._expr_val_str(cond_expr)))
1718                 implies_str = "\n".join(implies_str_rows)
1719
1720             res = _lines("Symbol " +
1721                            ("(no name)" if sc.name is None else sc.name),
1722                          "Type           : " + TYPENAME[sc.type],
1723                          "Value          : " + s(sc.get_value()),
1724                          "User value     : " + user_val_str,
1725                          "Visibility     : " + s(_get_visibility(sc)),
1726                          "Is choice item : " + BOOL_STR[sc.is_choice_sym],
1727                          "Is defined     : " + BOOL_STR[sc.is_defined_],
1728                          "Is from env.   : " + BOOL_STR[sc.is_from_env],
1729                          "Is special     : " + BOOL_STR[sc.is_special_] + "\n")
1730             if sc.ranges:
1731                 res += _lines("Ranges:", ranges_str + "\n")
1732             res += _lines("Prompts:",
1733                           prompts_str,
1734                           "Default values:",
1735                           defaults_str,
1736                           "Selects:",
1737                           selects_str,
1738                           "Implies:",
1739                           implies_str,
1740                           "Reverse (select-related) dependencies:",
1741                           " (no reverse dependencies)"
1742                           if sc.rev_dep == "n"
1743                           else " " + self._expr_val_str(sc.rev_dep),
1744                           "Weak reverse (imply-related) dependencies:",
1745                           " (no weak reverse dependencies)"
1746                           if sc.weak_rev_dep == "n"
1747                           else " " + self._expr_val_str(sc.weak_rev_dep),
1748                           "Additional dependencies from enclosing menus "
1749                             "and ifs:",
1750                           additional_deps_str,
1751                           "Locations: " + locations_str)
1752
1753             return res
1754
1755         #
1756         # Choice-specific stuff
1757         #
1758
1759         # Build selected symbol string
1760         sel = sc.get_selection()
1761         sel_str = "(no selection)" if sel is None else sel.name
1762
1763         # Build default values string
1764         if not sc.def_exprs:
1765             defaults_str = " (no default values)"
1766         else:
1767             defaults_str_rows = []
1768             for sym, cond_expr in sc.orig_def_exprs:
1769                 defaults_str_rows.append(
1770                     " {0}".format(sym.name) if cond_expr is None else
1771                     " {0} if {1}".format(sym.name,
1772                                          self._expr_val_str(cond_expr)))
1773             defaults_str = "\n".join(defaults_str_rows)
1774
1775         # Build contained symbols string
1776         names = [sym.name for sym in sc.actual_symbols]
1777         syms_string = " ".join(names) if names else "(empty)"
1778
1779         return _lines("Choice",
1780                       "Name (for named choices): " +
1781                         ("(no name)" if sc.name is None else sc.name),
1782                       "Type            : " + TYPENAME[sc.type],
1783                       "Selected symbol : " + sel_str,
1784                       "User value      : " + user_val_str,
1785                       "Mode            : " + s(sc.get_mode()),
1786                       "Visibility      : " + s(_get_visibility(sc)),
1787                       "Optional        : " + BOOL_STR[sc.optional],
1788                       "Prompts:",
1789                       prompts_str,
1790                       "Defaults:",
1791                       defaults_str,
1792                       "Choice symbols:",
1793                       " " + syms_string,
1794                       "Additional dependencies from enclosing menus and "
1795                         "ifs:",
1796                       additional_deps_str,
1797                       "Locations: " + locations_str)
1798
1799     def _warn(self, msg, filename=None, linenr=None):
1800         """For printing warnings to stderr."""
1801         msg = _build_msg("warning: " + msg, filename, linenr)
1802         if self.print_warnings:
1803             sys.stderr.write(msg + "\n")
1804         self._warnings.append(msg)
1805
1806 class Item(object):
1807
1808     """Base class for symbols and other Kconfig constructs. Subclasses are
1809     Symbol, Choice, Menu, and Comment."""
1810
1811     def is_symbol(self):
1812         """Returns True if the item is a symbol. Short for
1813         isinstance(item, kconfiglib.Symbol)."""
1814         return isinstance(self, Symbol)
1815
1816     def is_choice(self):
1817         """Returns True if the item is a choice. Short for
1818         isinstance(item, kconfiglib.Choice)."""
1819         return isinstance(self, Choice)
1820
1821     def is_menu(self):
1822         """Returns True if the item is a menu. Short for
1823         isinstance(item, kconfiglib.Menu)."""
1824         return isinstance(self, Menu)
1825
1826     def is_comment(self):
1827         """Returns True if the item is a comment. Short for
1828         isinstance(item, kconfiglib.Comment)."""
1829         return isinstance(self, Comment)
1830
1831 class Symbol(Item):
1832
1833     """Represents a configuration symbol - e.g. FOO for
1834
1835     config FOO
1836         ..."""
1837
1838     #
1839     # Public interface
1840     #
1841
1842     def get_config(self):
1843         """Returns the Config instance this symbol is from."""
1844         return self.config
1845
1846     def get_name(self):
1847         """Returns the name of the symbol."""
1848         return self.name
1849
1850     def get_type(self):
1851         """Returns the type of the symbol: one of UNKNOWN, BOOL, TRISTATE,
1852         STRING, HEX, or INT. These are defined at the top level of the module,
1853         so you'd do something like
1854
1855         if sym.get_type() == kconfiglib.STRING:
1856             ..."""
1857         return self.type
1858
1859     def get_prompts(self):
1860         """Returns a list of prompts defined for the symbol, in the order they
1861         appear in the configuration files. Returns the empty list for symbols
1862         with no prompt.
1863
1864         This list will have a single entry for the vast majority of symbols
1865         having prompts, but having multiple prompts for a single symbol is
1866         possible through having multiple 'config' entries for it."""
1867         return [prompt for prompt, _ in self.orig_prompts]
1868
1869     def get_help(self):
1870         """Returns the help text of the symbol, or None if the symbol has no
1871         help text."""
1872         return self.help
1873
1874     def get_parent(self):
1875         """Returns the menu or choice statement that contains the symbol, or
1876         None if the symbol is at the top level. Note that if statements are
1877         treated as syntactic and do not have an explicit class
1878         representation."""
1879         return self.parent
1880
1881     def get_def_locations(self):
1882         """Returns a list of (filename, linenr) tuples, where filename (string)
1883         and linenr (int) represent a location where the symbol is defined. For
1884         the vast majority of symbols this list will only contain one element.
1885         For the following Kconfig, FOO would get two entries: the lines marked
1886         with *.
1887
1888         config FOO *
1889             bool "foo prompt 1"
1890
1891         config FOO *
1892             bool "foo prompt 2"
1893         """
1894         return self.def_locations
1895
1896     def get_ref_locations(self):
1897         """Returns a list of (filename, linenr) tuples, where filename (string)
1898         and linenr (int) represent a location where the symbol is referenced in
1899         the configuration. For example, the lines marked by * would be included
1900         for FOO below:
1901
1902         config A
1903             bool
1904             default BAR || FOO *
1905
1906         config B
1907             tristate
1908             depends on FOO *
1909             default m if FOO *
1910
1911         if FOO *
1912             config A
1913                 bool "A"
1914         endif
1915
1916         config FOO (definition not included)
1917             bool
1918         """
1919         return self.ref_locations
1920
1921     def get_value(self):
1922         """Calculate and return the value of the symbol. See also
1923         Symbol.set_user_value()."""
1924
1925         if self.cached_val is not None:
1926             return self.cached_val
1927
1928         # As a quirk of Kconfig, undefined symbols get their name as their
1929         # value. This is why things like "FOO = bar" work for seeing if FOO has
1930         # the value "bar".
1931         if self.type == UNKNOWN:
1932             self.cached_val = self.name
1933             return self.name
1934
1935         new_val = DEFAULT_VALUE[self.type]
1936         vis = _get_visibility(self)
1937
1938         # This is easiest to calculate together with the value
1939         self.write_to_conf = False
1940
1941         if self.type == BOOL or self.type == TRISTATE:
1942             # The visibility and mode (modules-only or single-selection) of
1943             # choice items will be taken into account in _get_visibility()
1944             if self.is_choice_sym:
1945                 if vis != "n":
1946                     choice = self.parent
1947                     mode = choice.get_mode()
1948
1949                     self.write_to_conf = (mode != "n")
1950
1951                     if mode == "y":
1952                         new_val = "y" if choice.get_selection() is self \
1953                                   else "n"
1954                     elif mode == "m":
1955                         if self.user_val == "m" or self.user_val == "y":
1956                             new_val = "m"
1957
1958             else:
1959                 # If the symbol is visible and has a user value, use that.
1960                 # Otherwise, look at defaults and weak reverse dependencies
1961                 # (implies).
1962                 use_defaults_and_weak_rev_deps = True
1963
1964                 if vis != "n":
1965                     self.write_to_conf = True
1966                     if self.user_val is not None:
1967                         new_val = self.config._eval_min(self.user_val, vis)
1968                         use_defaults_and_weak_rev_deps = False
1969
1970                 if use_defaults_and_weak_rev_deps:
1971                     for val_expr, cond_expr in self.def_exprs:
1972                         cond_eval = self.config._eval_expr(cond_expr)
1973                         if cond_eval != "n":
1974                             self.write_to_conf = True
1975                             new_val = self.config._eval_min(val_expr,
1976                                                             cond_eval)
1977                             break
1978
1979                     weak_rev_dep_val = \
1980                         self.config._eval_expr(self.weak_rev_dep)
1981                     if weak_rev_dep_val != "n":
1982                         self.write_to_conf = True
1983                         new_val = self.config._eval_max(new_val,
1984                                                         weak_rev_dep_val)
1985
1986                 # Reverse (select-related) dependencies take precedence
1987                 rev_dep_val = self.config._eval_expr(self.rev_dep)
1988                 if rev_dep_val != "n":
1989                     self.write_to_conf = True
1990                     new_val = self.config._eval_max(new_val, rev_dep_val)
1991
1992             # We need to promote "m" to "y" in two circumstances:
1993             #  1) If our type is boolean
1994             #  2) If our weak_rev_dep (from IMPLY) is "y"
1995             if new_val == "m" and \
1996                (self.type == BOOL or
1997                 self.config._eval_expr(self.weak_rev_dep) == "y"):
1998                 new_val = "y"
1999
2000         elif self.type == INT or self.type == HEX:
2001             has_active_range = False
2002             low = None
2003             high = None
2004             use_defaults = True
2005
2006             base = 16 if self.type == HEX else 10
2007
2008             for l, h, cond_expr in self.ranges:
2009                 if self.config._eval_expr(cond_expr) != "n":
2010                     has_active_range = True
2011
2012                     low_str = _str_val(l)
2013                     high_str = _str_val(h)
2014                     low = int(low_str, base) if \
2015                       _is_base_n(low_str, base) else 0
2016                     high = int(high_str, base) if \
2017                       _is_base_n(high_str, base) else 0
2018
2019                     break
2020
2021             if vis != "n":
2022                 self.write_to_conf = True
2023
2024                 if self.user_val is not None and \
2025                    _is_base_n(self.user_val, base) and \
2026                    (not has_active_range or
2027                     low <= int(self.user_val, base) <= high):
2028
2029                     # If the user value is OK, it is stored in exactly the same
2030                     # form as specified in the assignment (with or without
2031                     # "0x", etc).
2032
2033                     use_defaults = False
2034                     new_val = self.user_val
2035
2036             if use_defaults:
2037                 for val_expr, cond_expr in self.def_exprs:
2038                     if self.config._eval_expr(cond_expr) != "n":
2039                         self.write_to_conf = True
2040
2041                         # If the default value is OK, it is stored in exactly
2042                         # the same form as specified. Otherwise, it is clamped
2043                         # to the range, and the output has "0x" as appropriate
2044                         # for the type.
2045
2046                         new_val = _str_val(val_expr)
2047
2048                         if _is_base_n(new_val, base):
2049                             new_val_num = int(new_val, base)
2050                             if has_active_range:
2051                                 clamped_val = None
2052
2053                                 if new_val_num < low:
2054                                     clamped_val = low
2055                                 elif new_val_num > high:
2056                                     clamped_val = high
2057
2058                                 if clamped_val is not None:
2059                                     new_val = (hex(clamped_val) if \
2060                                       self.type == HEX else str(clamped_val))
2061
2062                             break
2063                 else: # For the for loop
2064                     # If no user value or default kicks in but the hex/int has
2065                     # an active range, then the low end of the range is used,
2066                     # provided it's > 0, with "0x" prepended as appropriate.
2067                     if has_active_range and low > 0:
2068                         new_val = (hex(low) if self.type == HEX else str(low))
2069
2070         elif self.type == STRING:
2071             use_defaults = True
2072
2073             if vis != "n":
2074                 self.write_to_conf = True
2075                 if self.user_val is not None:
2076                     new_val = self.user_val
2077                     use_defaults = False
2078
2079             if use_defaults:
2080                 for val_expr, cond_expr in self.def_exprs:
2081                     if self.config._eval_expr(cond_expr) != "n":
2082                         self.write_to_conf = True
2083                         new_val = _str_val(val_expr)
2084                         break
2085
2086         self.cached_val = new_val
2087         return new_val
2088
2089     def get_user_value(self):
2090         """Returns the value assigned to the symbol in a .config or via
2091         Symbol.set_user_value() (provided the value was valid for the type of
2092         the symbol). Returns None in case of no user value."""
2093         return self.user_val
2094
2095     def get_upper_bound(self):
2096         """For string/hex/int symbols and for bool and tristate symbols that
2097         cannot be modified (see is_modifiable()), returns None.
2098
2099         Otherwise, returns the highest value the symbol can be set to with
2100         Symbol.set_user_value() (that will not be truncated): one of "m" or
2101         "y", arranged from lowest to highest. This corresponds to the highest
2102         value the symbol could be given in e.g. the 'make menuconfig'
2103         interface.
2104
2105         See also the tri_less*() and tri_greater*() functions, which could come
2106         in handy."""
2107         if self.type != BOOL and self.type != TRISTATE:
2108             return None
2109         rev_dep = self.config._eval_expr(self.rev_dep)
2110         # A bool selected to "m" gets promoted to "y", pinning it
2111         if rev_dep == "m" and self.type == BOOL:
2112             return None
2113         vis = _get_visibility(self)
2114         if TRI_TO_INT[vis] > TRI_TO_INT[rev_dep]:
2115             return vis
2116         return None
2117
2118     def get_lower_bound(self):
2119         """For string/hex/int symbols and for bool and tristate symbols that
2120         cannot be modified (see is_modifiable()), returns None.
2121
2122         Otherwise, returns the lowest value the symbol can be set to with
2123         Symbol.set_user_value() (that will not be truncated): one of "n" or
2124         "m", arranged from lowest to highest. This corresponds to the lowest
2125         value the symbol could be given in e.g. the 'make menuconfig'
2126         interface.
2127
2128         See also the tri_less*() and tri_greater*() functions, which could come
2129         in handy."""
2130         if self.type != BOOL and self.type != TRISTATE:
2131             return None
2132         rev_dep = self.config._eval_expr(self.rev_dep)
2133         # A bool selected to "m" gets promoted to "y", pinning it
2134         if rev_dep == "m" and self.type == BOOL:
2135             return None
2136         if TRI_TO_INT[_get_visibility(self)] > TRI_TO_INT[rev_dep]:
2137             return rev_dep
2138         return None
2139
2140     def get_assignable_values(self):
2141         """For string/hex/int symbols and for bool and tristate symbols that
2142         cannot be modified (see is_modifiable()), returns the empty list.
2143
2144         Otherwise, returns a list containing the user values that can be
2145         assigned to the symbol (that won't be truncated). Usage example:
2146
2147         if "m" in sym.get_assignable_values():
2148             sym.set_user_value("m")
2149
2150         This is basically a more convenient interface to
2151         get_lower/upper_bound() when wanting to test if a particular tristate
2152         value can be assigned."""
2153         if self.type != BOOL and self.type != TRISTATE:
2154             return []
2155         rev_dep = self.config._eval_expr(self.rev_dep)
2156         # A bool selected to "m" gets promoted to "y", pinning it
2157         if rev_dep == "m" and self.type == BOOL:
2158             return []
2159         res = ["n", "m", "y"][TRI_TO_INT[rev_dep] :
2160                               TRI_TO_INT[_get_visibility(self)] + 1]
2161         return res if len(res) > 1 else []
2162
2163     def get_visibility(self):
2164         """Returns the visibility of the symbol: one of "n", "m" or "y". For
2165         bool and tristate symbols, this is an upper bound on the value users
2166         can set for the symbol. For other types of symbols, a visibility of "n"
2167         means the user value will be ignored. A visibility of "n" corresponds
2168         to not being visible in the 'make *config' interfaces.
2169
2170         Example (assuming we're running with modules enabled -- i.e., MODULES
2171         set to 'y'):
2172
2173         # Assume this has been assigned 'n'
2174         config N_SYM
2175             tristate "N_SYM"
2176
2177         # Assume this has been assigned 'm'
2178         config M_SYM
2179             tristate "M_SYM"
2180
2181         # Has visibility 'n'
2182         config A
2183             tristate "A"
2184             depends on N_SYM
2185
2186         # Has visibility 'm'
2187         config B
2188             tristate "B"
2189             depends on M_SYM
2190
2191         # Has visibility 'y'
2192         config C
2193             tristate "C"
2194
2195         # Has no prompt, and hence visibility 'n'
2196         config D
2197             tristate
2198
2199         Having visibility be tri-valued ensures that e.g. a symbol cannot be
2200         set to "y" by the user if it depends on a symbol with value "m", which
2201         wouldn't be safe.
2202
2203         You should probably look at get_lower/upper_bound(),
2204         get_assignable_values() and is_modifiable() before using this."""
2205         return _get_visibility(self)
2206
2207     def get_referenced_symbols(self, refs_from_enclosing=False):
2208         """Returns the set() of all symbols referenced by this symbol. For
2209         example, the symbol defined by
2210
2211         config FOO
2212             bool
2213             prompt "foo" if A && B
2214             default C if D
2215             depends on E
2216             select F if G
2217
2218         references the symbols A through G.
2219
2220         refs_from_enclosing (default: False): If True, the symbols referenced
2221            by enclosing menus and ifs will be included in the result."""
2222         return self.all_referenced_syms if refs_from_enclosing else \
2223                self.referenced_syms
2224
2225     def get_selected_symbols(self):
2226         """Returns the set() of all symbols X for which this symbol has a
2227         'select X' or 'select X if Y' (regardless of whether Y is satisfied or
2228         not). This is a subset of the symbols returned by
2229         get_referenced_symbols()."""
2230         return self.selected_syms
2231
2232     def get_implied_symbols(self):
2233         """Returns the set() of all symbols X for which this symbol has an
2234         'imply X' or 'imply X if Y' (regardless of whether Y is satisfied or
2235         not). This is a subset of the symbols returned by
2236         get_referenced_symbols()."""
2237         return self.implied_syms
2238
2239     def set_user_value(self, v):
2240         """Sets the user value of the symbol.
2241
2242         Equal in effect to assigning the value to the symbol within a .config
2243         file. Use get_lower/upper_bound() or get_assignable_values() to find
2244         the range of currently assignable values for bool and tristate symbols;
2245         setting values outside this range will cause the user value to differ
2246         from the result of Symbol.get_value() (be truncated). Values that are
2247         invalid for the type (such as a_bool.set_user_value("foo")) are
2248         ignored, and a warning is emitted if an attempt is made to assign such
2249         a value.
2250
2251         For any type of symbol, is_modifiable() can be used to check if a user
2252         value will currently have any effect on the symbol, as determined by
2253         its visibility and range of assignable values. Any value that is valid
2254         for the type (bool, tristate, etc.) will end up being reflected in
2255         get_user_value() though, and might have an effect later if conditions
2256         change. To get rid of the user value, use unset_user_value().
2257
2258         Any symbols dependent on the symbol are (recursively) invalidated, so
2259         things will just work with regards to dependencies.
2260
2261         v: The user value to give to the symbol."""
2262         self._set_user_value_no_invalidate(v, False)
2263
2264         # There might be something more efficient you could do here, but play
2265         # it safe.
2266         if self.name == "MODULES":
2267             self.config._invalidate_all()
2268             return
2269
2270         self._invalidate()
2271         self._invalidate_dependent()
2272
2273     def unset_user_value(self):
2274         """Resets the user value of the symbol, as if the symbol had never
2275         gotten a user value via Config.load_config() or
2276         Symbol.set_user_value()."""
2277         self._unset_user_value_no_recursive_invalidate()
2278         self._invalidate_dependent()
2279
2280     def is_modifiable(self):
2281         """Returns True if the value of the symbol could be modified by calling
2282         Symbol.set_user_value().
2283
2284         For bools and tristates, this corresponds to the symbol being visible
2285         in the 'make menuconfig' interface and not already being pinned to a
2286         specific value (e.g. because it is selected by another symbol).
2287
2288         For strings and numbers, this corresponds to just being visible. (See
2289         Symbol.get_visibility().)"""
2290         if self.is_special_:
2291             return False
2292         if self.type == BOOL or self.type == TRISTATE:
2293             rev_dep = self.config._eval_expr(self.rev_dep)
2294             # A bool selected to "m" gets promoted to "y", pinning it
2295             if rev_dep == "m" and self.type == BOOL:
2296                 return False
2297             return TRI_TO_INT[_get_visibility(self)] > TRI_TO_INT[rev_dep]
2298         return _get_visibility(self) != "n"
2299
2300     def is_defined(self):
2301         """Returns False if the symbol is referred to in the Kconfig but never
2302         actually defined."""
2303         return self.is_defined_
2304
2305     def is_special(self):
2306         """Returns True if the symbol is one of the special symbols n, m, y, or
2307         UNAME_RELEASE, or gets its value from the environment."""
2308         return self.is_special_
2309
2310     def is_from_environment(self):
2311         """Returns True if the symbol gets its value from the environment."""
2312         return self.is_from_env
2313
2314     def has_ranges(self):
2315         """Returns True if the symbol is of type INT or HEX and has ranges that
2316         limit what values it can take on."""
2317         return bool(self.ranges)
2318
2319     def is_choice_symbol(self):
2320         """Returns True if the symbol is in a choice statement and is an actual
2321         choice symbol (see Choice.get_symbols())."""
2322         return self.is_choice_sym
2323
2324     def is_choice_selection(self):
2325         """Returns True if the symbol is contained in a choice statement and is
2326         the selected item. Equivalent to
2327
2328         sym.is_choice_symbol() and sym.get_parent().get_selection() is sym"""
2329         return self.is_choice_sym and self.parent.get_selection() is self
2330
2331     def is_allnoconfig_y(self):
2332         """Returns True if the symbol has the 'allnoconfig_y' option set."""
2333         return self.allnoconfig_y
2334
2335     def __str__(self):
2336         """Returns a string containing various information about the symbol."""
2337         return self.config._get_sym_or_choice_str(self)
2338
2339     #
2340     # Private methods
2341     #
2342
2343     def __init__(self):
2344         """Symbol constructor -- not intended to be called directly by
2345         Kconfiglib clients."""
2346
2347         self.name = None
2348         self.type = UNKNOWN
2349         self.prompts = []
2350         self.def_exprs = [] # 'default' properties
2351         self.ranges = [] # 'range' properties (for int and hex)
2352         self.help = None # Help text
2353         self.rev_dep = "n" # Reverse (select-related) dependencies
2354         self.weak_rev_dep = "n" # Weak reverse (imply-related) dependencies
2355         self.config = None
2356         self.parent = None
2357
2358         self.user_val = None # Value set by user
2359
2360         # The prompt, default value, select, and imply conditions without any
2361         # dependencies from menus and ifs propagated to them
2362         self.orig_prompts = []
2363         self.orig_def_exprs = []
2364         self.orig_selects = []
2365         self.orig_implies = []
2366
2367         # Dependencies inherited from containing menus and ifs
2368         self.deps_from_containing = None
2369         # The set of symbols referenced by this symbol (see
2370         # get_referenced_symbols())
2371         self.referenced_syms = set()
2372         # The set of symbols selected by this symbol (see
2373         # get_selected_symbols())
2374         self.selected_syms = set()
2375         # The set of symbols implied by this symbol (see get_implied_symbols())
2376         self.implied_syms = set()
2377         # Like 'referenced_syms', but includes symbols from
2378         # dependencies inherited from enclosing menus and ifs
2379         self.all_referenced_syms = set()
2380
2381         # This records only dependencies from enclosing ifs and menus together
2382         # with local 'depends on' dependencies. Needed when determining actual
2383         # choice items (hrrrr...). See Choice._determine_actual_symbols().
2384         self.menu_dep = None
2385
2386         # See Symbol.get_ref/def_locations().
2387         self.def_locations = []
2388         self.ref_locations = []
2389
2390         # Populated in Config._build_dep() after parsing. Links the symbol to
2391         # the symbols that immediately depend on it (in a caching/invalidation
2392         # sense). The total set of dependent symbols for the symbol (the
2393         # transitive closure) is calculated on an as-needed basis in
2394         # _get_dependent().
2395         self.dep = set()
2396
2397         # Cached values
2398
2399         # Caches the calculated value
2400         self.cached_val = None
2401         # Caches the visibility, which acts as an upper bound on the value
2402         self.cached_visibility = None
2403         # Caches the total list of dependent symbols. Calculated in
2404         # _get_dependent().
2405         self.cached_deps = None
2406
2407         # Flags
2408
2409         # Does the symbol have an entry in the Kconfig file? The trailing
2410         # underscore avoids a collision with is_defined().
2411         self.is_defined_ = False
2412         # Should the symbol get an entry in .config?
2413         self.write_to_conf = False
2414         # Set to true when _make_conf() is called on a symbol, so that symbols
2415         # defined in multiple locations only get one .config entry. We need to
2416         # reset it prior to writing out a new .config.
2417         self.already_written = False
2418         # This is set to True for "actual" choice symbols; see
2419         # Choice._determine_actual_symbols().
2420         self.is_choice_sym = False
2421         # Does the symbol get its value in some special way, e.g. from the
2422         # environment or by being one of the special symbols n, m, and y? If
2423         # so, the value is stored in self.cached_val, which is never
2424         # invalidated. The trailing underscore avoids a collision with
2425         # is_special().
2426         self.is_special_ = False
2427         # Does the symbol get its value from the environment?
2428         self.is_from_env = False
2429         # Does the symbol have the 'allnoconfig_y' option set?
2430         self.allnoconfig_y = False
2431
2432     def _invalidate(self):
2433         if self.is_special_:
2434             return
2435
2436         if self.is_choice_sym:
2437             self.parent._invalidate()
2438
2439         self.cached_val = None
2440         self.cached_visibility = None
2441
2442     def _invalidate_dependent(self):
2443         for sym in self._get_dependent():
2444             sym._invalidate()
2445
2446     def _set_user_value_no_invalidate(self, v, suppress_load_warnings):
2447         """Like set_user_value(), but does not invalidate any symbols.
2448
2449         suppress_load_warnings: some warnings are annoying when loading a
2450            .config that can be helpful when manually invoking set_user_value().
2451            This flag is set to True to suppress such warnings.
2452
2453            Perhaps this could be made optional for load_config() instead."""
2454
2455         if self.is_special_:
2456             if self.is_from_env:
2457                 self.config._warn('attempt to assign the value "{0}" to the '
2458                                   'symbol {1}, which gets its value from the '
2459                                   'environment. Assignment ignored.'
2460                                   .format(v, self.name))
2461             else:
2462                 self.config._warn('attempt to assign the value "{0}" to the '
2463                                   'special symbol {1}. Assignment ignored.'
2464                                   .format(v, self.name))
2465             return
2466
2467         if not self.is_defined_:
2468             filename, linenr = self.ref_locations[0]
2469             if self.config.print_undef_assign:
2470                 _stderr_msg('note: attempt to assign the value "{0}" to {1}, '
2471                             "which is referenced at {2}:{3} but never "
2472                             "defined. Assignment ignored."
2473                             .format(v, self.name, filename, linenr))
2474             return
2475
2476         # Check if the value is valid for our type
2477         if not ((self.type == BOOL     and (v == "y" or v == "n")   ) or
2478                 (self.type == TRISTATE and (v == "y" or v == "m" or
2479                                             v == "n")               ) or
2480                 (self.type == STRING                                ) or
2481                 (self.type == INT      and _is_base_n(v, 10)        ) or
2482                 (self.type == HEX      and _is_base_n(v, 16)        )):
2483             self.config._warn('the value "{0}" is invalid for {1}, which has '
2484                               "type {2}. Assignment ignored."
2485                               .format(v, self.name, TYPENAME[self.type]))
2486             return
2487
2488         if not self.prompts and not suppress_load_warnings:
2489             self.config._warn('assigning "{0}" to the symbol {1} which '
2490                               'lacks prompts and thus has visibility "n". '
2491                               'The assignment will have no effect.'
2492                               .format(v, self.name))
2493
2494         self.user_val = v
2495
2496         if self.is_choice_sym and (self.type == BOOL or self.type == TRISTATE):
2497             choice = self.parent
2498             if v == "y":
2499                 choice.user_val = self
2500                 choice.user_mode = "y"
2501             elif v == "m":
2502                 choice.user_val = None
2503                 choice.user_mode = "m"
2504
2505     def _unset_user_value_no_recursive_invalidate(self):
2506         self._invalidate()
2507         self.user_val = None
2508
2509         if self.is_choice_sym:
2510             self.parent._unset_user_value()
2511
2512     def _make_conf(self, append_fn):
2513         if self.already_written:
2514             return
2515
2516         self.already_written = True
2517
2518         # Note: write_to_conf is determined in get_value()
2519         val = self.get_value()
2520         if not self.write_to_conf:
2521             return
2522
2523         if self.type == BOOL or self.type == TRISTATE:
2524             append_fn("{0}{1}={2}".format(self.config.config_prefix, self.name, val)
2525                       if val == "y" or val == "m" else
2526                       "# {0}{1} is not set".format(self.config.config_prefix, self.name))
2527
2528         elif self.type == INT or self.type == HEX:
2529             append_fn("{0}{1}={2}".format(self.config.config_prefix, self.name, val))
2530
2531         elif self.type == STRING:
2532             # Escape \ and "
2533             append_fn('{0}{1}="{2}"'
2534                       .format(self.config.config_prefix, self.name,
2535                               val.replace("\\", "\\\\").replace('"', '\\"')))
2536
2537         else:
2538             _internal_error("Internal error while creating .config: unknown "
2539                             'type "{0}".'.format(self.type))
2540
2541     def _get_dependent(self):
2542         """Returns the set of symbols that should be invalidated if the value
2543         of the symbol changes, because they might be affected by the change.
2544         Note that this is an internal API -- it's probably of limited
2545         usefulness to clients."""
2546         if self.cached_deps is not None:
2547             return self.cached_deps
2548
2549         res = set(self.dep)
2550         for s in self.dep:
2551             res |= s._get_dependent()
2552
2553         if self.is_choice_sym:
2554             # Choice symbols also depend (recursively) on their siblings. The
2555             # siblings are not included in 'dep' to avoid dependency loops.
2556             for sibling in self.parent.actual_symbols:
2557                 if sibling is not self:
2558                     res.add(sibling)
2559                     res |= sibling.dep
2560                     for s in sibling.dep:
2561                         res |= s._get_dependent()
2562
2563         self.cached_deps = res
2564         return res
2565
2566     def _has_auto_menu_dep_on(self, on):
2567         """See Choice._determine_actual_symbols()."""
2568         if not isinstance(self.parent, Choice):
2569             _internal_error("Attempt to determine auto menu dependency for "
2570                             "symbol ouside of choice.")
2571
2572         if not self.prompts:
2573             # If we have no prompt, use the menu dependencies instead (what was
2574             # specified with 'depends on')
2575             return self.menu_dep is not None and \
2576                    self.config._expr_depends_on(self.menu_dep, on)
2577
2578         for _, cond_expr in self.prompts:
2579             if self.config._expr_depends_on(cond_expr, on):
2580                 return True
2581
2582         return False
2583
2584 class Menu(Item):
2585
2586     """Represents a menu statement."""
2587
2588     #
2589     # Public interface
2590     #
2591
2592     def get_config(self):
2593         """Return the Config instance this menu is from."""
2594         return self.config
2595
2596     def get_title(self):
2597         """Returns the title text of the menu."""
2598         return self.title
2599
2600     def get_parent(self):
2601         """Returns the menu or choice statement that contains the menu, or
2602         None if the menu is at the top level. Note that if statements are
2603         treated as syntactic sugar and do not have an explicit class
2604         representation."""
2605         return self.parent
2606
2607     def get_location(self):
2608         """Returns the location of the menu as a (filename, linenr) tuple,
2609         where filename is a string and linenr an int."""
2610         return (self.filename, self.linenr)
2611
2612     def get_items(self, recursive=False):
2613         """Returns a list containing the items (symbols, menus, choice
2614         statements and comments) in in the menu, in the same order that the
2615         items appear within the menu.
2616
2617         recursive (default: False): True if items contained in items within the
2618            menu should be included recursively (preorder)."""
2619
2620         if not recursive:
2621             return self.block
2622
2623         res = []
2624         for item in self.block:
2625             res.append(item)
2626             if isinstance(item, Menu):
2627                 res.extend(item.get_items(True))
2628             elif isinstance(item, Choice):
2629                 res.extend(item.get_items())
2630         return res
2631
2632     def get_symbols(self, recursive=False):
2633         """Returns a list containing the symbols in the menu, in the same order
2634         that they appear within the menu.
2635
2636         recursive (default: False): True if symbols contained in items within
2637            the menu should be included recursively."""
2638
2639         return [item for item in self.get_items(recursive) if
2640                 isinstance(item, Symbol)]
2641
2642     def get_visibility(self):
2643         """Returns the visibility of the menu. This also affects the visibility
2644         of subitems. See also Symbol.get_visibility()."""
2645         return self.config._eval_expr(self.dep_expr)
2646
2647     def get_visible_if_visibility(self):
2648         """Returns the visibility the menu gets from its 'visible if'
2649         condition. "y" if the menu has no 'visible if' condition."""
2650         return self.config._eval_expr(self.visible_if_expr)
2651
2652     def get_referenced_symbols(self, refs_from_enclosing=False):
2653         """See Symbol.get_referenced_symbols()."""
2654         return self.all_referenced_syms if refs_from_enclosing else \
2655                self.referenced_syms
2656
2657     def __str__(self):
2658         """Returns a string containing various information about the menu."""
2659         depends_on_str = self.config._expr_val_str(self.orig_deps,
2660                                                    "(no dependencies)")
2661         visible_if_str = self.config._expr_val_str(self.visible_if_expr,
2662                                                    "(no dependencies)")
2663
2664         additional_deps_str = " " + \
2665           self.config._expr_val_str(self.deps_from_containing,
2666                                     "(no additional dependencies)")
2667
2668         return _lines("Menu",
2669                       "Title                     : " + self.title,
2670                       "'depends on' dependencies : " + depends_on_str,
2671                       "'visible if' dependencies : " + visible_if_str,
2672                       "Additional dependencies from enclosing menus and "
2673                         "ifs:",
2674                       additional_deps_str,
2675                       "Location: {0}:{1}".format(self.filename, self.linenr))
2676
2677     #
2678     # Private methods
2679     #
2680
2681     def __init__(self):
2682         """Menu constructor -- not intended to be called directly by
2683         Kconfiglib clients."""
2684
2685         self.title = None
2686         self.dep_expr = None
2687         self.visible_if_expr = None
2688         self.block = [] # List of contained items
2689         self.config = None
2690         self.parent = None
2691
2692         # Dependency expression without dependencies from enclosing menus and
2693         # ifs propagated
2694         self.orig_deps = None
2695
2696         # Dependencies inherited from containing menus and ifs
2697         self.deps_from_containing = None
2698         # The set of symbols referenced by this menu (see
2699         # get_referenced_symbols())
2700         self.referenced_syms = set()
2701         # Like 'referenced_syms', but includes symbols from
2702         # dependencies inherited from enclosing menus and ifs
2703         self.all_referenced_syms = None
2704
2705         self.filename = None
2706         self.linenr = None
2707
2708     def _make_conf(self, append_fn):
2709         if self.config._eval_expr(self.dep_expr) != "n" and \
2710            self.config._eval_expr(self.visible_if_expr) != "n":
2711             append_fn("\n#\n# {0}\n#".format(self.title))
2712         _make_block_conf(self.block, append_fn)
2713
2714 class Choice(Item):
2715
2716     """Represents a choice statement. A choice can be in one of three modes:
2717
2718     "n" - The choice is not visible and no symbols can be selected.
2719
2720     "m" - Any number of symbols can be set to "m". The rest will be "n". This
2721           is safe since potentially conflicting options don't actually get
2722           compiled into the kernel simultaneously with "m".
2723
2724     "y" - One symbol will be "y" while the rest are "n".
2725
2726     Only tristate choices can be in "m" mode, and the visibility of the choice
2727     is an upper bound on the mode, so that e.g. a choice that depends on a
2728     symbol with value "m" will be in "m" mode.
2729
2730     The mode changes automatically when a value is assigned to a symbol within
2731     the choice.
2732
2733     See Symbol.get_visibility() too."""
2734
2735     #
2736     # Public interface
2737     #
2738
2739     def get_config(self):
2740         """Returns the Config instance this choice is from."""
2741         return self.config
2742
2743     def get_name(self):
2744         """For named choices, returns the name. Returns None for unnamed
2745         choices. No named choices appear anywhere in the kernel Kconfig files
2746         as of Linux 3.7.0-rc8."""
2747         return self.name
2748
2749     def get_type(self):
2750         """Returns the type of the choice. See Symbol.get_type()."""
2751         return self.type
2752
2753     def get_prompts(self):
2754         """Returns a list of prompts defined for the choice, in the order they
2755         appear in the configuration files. Returns the empty list for choices
2756         with no prompt.
2757
2758         This list will have a single entry for the vast majority of choices
2759         having prompts, but having multiple prompts for a single choice is
2760         possible through having multiple 'choice' entries for it (though I'm
2761         not sure if that ever happens in practice)."""
2762         return [prompt for prompt, _ in self.orig_prompts]
2763
2764     def get_help(self):
2765         """Returns the help text of the choice, or None if the choice has no
2766         help text."""
2767         return self.help
2768
2769     def get_parent(self):
2770         """Returns the menu or choice statement that contains the choice, or
2771         None if the choice is at the top level. Note that if statements are
2772         treated as syntactic sugar and do not have an explicit class
2773         representation."""
2774         return self.parent
2775
2776     def get_def_locations(self):
2777         """Returns a list of (filename, linenr) tuples, where filename (string)
2778         and linenr (int) represent a location where the choice is defined. For
2779         the vast majority of choices (all of them as of Linux 3.7.0-rc8) this
2780         list will only contain one element, but its possible for named choices
2781         to be defined in multiple locations."""
2782         return self.def_locations
2783
2784     def get_selection(self):
2785         """Returns the symbol selected (either by the user or through
2786         defaults), or None if either no symbol is selected or the mode is not
2787         "y"."""
2788         if self.cached_selection is not None:
2789             if self.cached_selection == NO_SELECTION:
2790                 return None
2791             return self.cached_selection
2792
2793         if self.get_mode() != "y":
2794             return self._cache_ret(None)
2795
2796         # User choice available?
2797         if self.user_val is not None and _get_visibility(self.user_val) == "y":
2798             return self._cache_ret(self.user_val)
2799
2800         if self.optional:
2801             return self._cache_ret(None)
2802
2803         return self._cache_ret(self.get_selection_from_defaults())
2804
2805     def get_selection_from_defaults(self):
2806         """Like Choice.get_selection(), but acts as if no symbol has been
2807         selected by the user and no 'optional' flag is in effect."""
2808
2809         if not self.actual_symbols:
2810             return None
2811
2812         for symbol, cond_expr in self.def_exprs:
2813             if self.config._eval_expr(cond_expr) != "n":
2814                 chosen_symbol = symbol
2815                 break
2816         else:
2817             chosen_symbol = self.actual_symbols[0]
2818
2819         # Is the chosen symbol visible?
2820         if _get_visibility(chosen_symbol) != "n":
2821             return chosen_symbol
2822         # Otherwise, pick the first visible symbol
2823         for sym in self.actual_symbols:
2824             if _get_visibility(sym) != "n":
2825                 return sym
2826         return None
2827
2828     def get_user_selection(self):
2829         """If the choice is in "y" mode and has a user-selected symbol, returns
2830         that symbol. Otherwise, returns None."""
2831         return self.user_val
2832
2833     def get_items(self):
2834         """Gets all items contained in the choice in the same order as within
2835         the configuration ("items" instead of "symbols" since choices and
2836         comments might appear within choices. This only happens in one place as
2837         of Linux 3.7.0-rc8, in drivers/usb/gadget/Kconfig)."""
2838         return self.block
2839
2840     def get_symbols(self):
2841         """Returns a list containing the choice's symbols.
2842
2843         A quirk (perhaps a bug) of Kconfig is that you can put items within a
2844         choice that will not be considered members of the choice insofar as
2845         selection is concerned. This happens for example if one symbol within a
2846         choice 'depends on' the symbol preceding it, or if you put non-symbol
2847         items within choices.
2848
2849         As of Linux 3.7.0-rc8, this seems to be used intentionally in one
2850         place: drivers/usb/gadget/Kconfig.
2851
2852         This function returns the "proper" symbols of the choice in the order
2853         they appear in the choice, excluding such items. If you want all items
2854         in the choice, use get_items()."""
2855         return self.actual_symbols
2856
2857     def get_referenced_symbols(self, refs_from_enclosing=False):
2858         """See Symbol.get_referenced_symbols()."""
2859         return self.all_referenced_syms if refs_from_enclosing else \
2860                self.referenced_syms
2861
2862     def get_visibility(self):
2863         """Returns the visibility of the choice statement: one of "n", "m" or
2864         "y". This acts as an upper limit on the mode of the choice (though bool
2865         choices can only have the mode "y"). See the class documentation for an
2866         explanation of modes."""
2867         return _get_visibility(self)
2868
2869     def get_mode(self):
2870         """Returns the mode of the choice. See the class documentation for
2871         an explanation of modes."""
2872         minimum_mode = "n" if self.optional else "m"
2873         mode = self.user_mode if self.user_mode is not None else minimum_mode
2874         mode = self.config._eval_min(mode, _get_visibility(self))
2875
2876         # Promote "m" to "y" for boolean choices
2877         if mode == "m" and self.type == BOOL:
2878             return "y"
2879
2880         return mode
2881
2882     def is_optional(self):
2883         """Returns True if the choice has the 'optional' flag set (and so will
2884         default to "n" mode)."""
2885         return self.optional
2886
2887     def __str__(self):
2888         """Returns a string containing various information about the choice
2889         statement."""
2890         return self.config._get_sym_or_choice_str(self)
2891
2892     #
2893     # Private methods
2894     #
2895
2896     def __init__(self):
2897         """Choice constructor -- not intended to be called directly by
2898         Kconfiglib clients."""
2899
2900         self.name = None # Yes, choices can be named
2901         self.type = UNKNOWN
2902         self.prompts = []
2903         self.def_exprs = [] # 'default' properties
2904         self.help = None # Help text
2905         self.block = [] # List of contained items
2906         self.config = None
2907         self.parent = None
2908
2909         self.user_val = None
2910         self.user_mode = None
2911
2912         # We need to filter out symbols that appear within the choice block but
2913         # are not considered choice items (see
2914         # Choice._determine_actual_symbols()) This list holds the "actual"
2915         # choice items.
2916         self.actual_symbols = []
2917
2918         # The prompts and default values without any dependencies from
2919         # enclosing menus and ifs propagated
2920         self.orig_prompts = []
2921         self.orig_def_exprs = []
2922
2923         # Dependencies inherited from containing menus and ifs
2924         self.deps_from_containing = None
2925         # The set of symbols referenced by this choice (see
2926         # get_referenced_symbols())
2927         self.referenced_syms = set()
2928         # Like 'referenced_syms', but includes symbols from
2929         # dependencies inherited from enclosing menus and ifs
2930         self.all_referenced_syms = set()
2931
2932         # See Choice.get_def_locations()
2933         self.def_locations = []
2934
2935         # Cached values
2936         self.cached_selection = None
2937         self.cached_visibility = None
2938
2939         self.optional = False
2940
2941     def _determine_actual_symbols(self):
2942         """If a symbol's visibility depends on the preceding symbol within a
2943         choice, it is no longer viewed as a choice item. (This is quite
2944         possibly a bug, but some things consciously use it... ugh. It stems
2945         from automatic submenu creation.) In addition, it's possible to have
2946         choices and comments within choices, and those shouldn't be considered
2947         choice items either. Only drivers/usb/gadget/Kconfig seems to depend on
2948         any of this. This method computes the "actual" items in the choice and
2949         sets the is_choice_sym flag on them (retrieved via is_choice_symbol()).
2950
2951         Don't let this scare you: an earlier version simply checked for a
2952         sequence of symbols where all symbols after the first appeared in the
2953         'depends on' expression of the first, and that worked fine.  The added
2954         complexity is to be future-proof in the event that
2955         drivers/usb/gadget/Kconfig turns even more sinister. It might very well
2956         be overkilling things (especially if that file is refactored ;)."""
2957
2958         # Items might depend on each other in a tree structure, so we need a
2959         # stack to keep track of the current tentative parent
2960         stack = []
2961
2962         for item in self.block:
2963             if not isinstance(item, Symbol):
2964                 stack = []
2965                 continue
2966
2967             while stack:
2968                 if item._has_auto_menu_dep_on(stack[-1]):
2969                     # The item should not be viewed as a choice item, so don't
2970                     # set item.is_choice_sym
2971                     stack.append(item)
2972                     break
2973                 else:
2974                     stack.pop()
2975             else:
2976                 item.is_choice_sym = True
2977                 self.actual_symbols.append(item)
2978                 stack.append(item)
2979
2980     def _cache_ret(self, selection):
2981         # As None is used to indicate the lack of a cached value we can't use
2982         # that to cache the fact that the choice has no selection. Instead, we
2983         # use the symbolic constant NO_SELECTION.
2984         if selection is None:
2985             self.cached_selection = NO_SELECTION
2986         else:
2987             self.cached_selection = selection
2988
2989         return selection
2990
2991     def _invalidate(self):
2992         self.cached_selection = None
2993         self.cached_visibility = None
2994
2995     def _unset_user_value(self):
2996         self._invalidate()
2997         self.user_val = None
2998         self.user_mode = None
2999
3000     def _make_conf(self, append_fn):
3001         _make_block_conf(self.block, append_fn)
3002
3003 class Comment(Item):
3004
3005     """Represents a comment statement."""
3006
3007     #
3008     # Public interface
3009     #
3010
3011     def get_config(self):
3012         """Returns the Config instance this comment is from."""
3013         return self.config
3014
3015     def get_text(self):
3016         """Returns the text of the comment."""
3017         return self.text
3018
3019     def get_parent(self):
3020         """Returns the menu or choice statement that contains the comment, or
3021         None if the comment is at the top level. Note that if statements are
3022         treated as syntactic sugar and do not have an explicit class
3023         representation."""
3024         return self.parent
3025
3026     def get_location(self):
3027         """Returns the location of the comment as a (filename, linenr) tuple,
3028         where filename is a string and linenr an int."""
3029         return (self.filename, self.linenr)
3030
3031     def get_visibility(self):
3032         """Returns the visibility of the comment. See also
3033         Symbol.get_visibility()."""
3034         return self.config._eval_expr(self.dep_expr)
3035
3036     def get_referenced_symbols(self, refs_from_enclosing=False):
3037         """See Symbol.get_referenced_symbols()."""
3038         return self.all_referenced_syms if refs_from_enclosing else \
3039                self.referenced_syms
3040
3041     def __str__(self):
3042         """Returns a string containing various information about the
3043         comment."""
3044         dep_str = self.config._expr_val_str(self.orig_deps,
3045                                             "(no dependencies)")
3046
3047         additional_deps_str = " " + \
3048           self.config._expr_val_str(self.deps_from_containing,
3049                                     "(no additional dependencies)")
3050
3051         return _lines("Comment",
3052                       "Text: "         + str(self.text),
3053                       "Dependencies: " + dep_str,
3054                       "Additional dependencies from enclosing menus and "
3055                         "ifs:",
3056                       additional_deps_str,
3057                       "Location: {0}:{1}".format(self.filename, self.linenr))
3058
3059     #
3060     # Private methods
3061     #
3062
3063     def __init__(self):
3064         """Comment constructor -- not intended to be called directly by
3065         Kconfiglib clients."""
3066
3067         self.text = None
3068         self.dep_expr = None
3069         self.config = None
3070         self.parent = None
3071
3072         # Dependency expression without dependencies from enclosing menus and
3073         # ifs propagated
3074         self.orig_deps = None
3075
3076         # Dependencies inherited from containing menus and ifs
3077         self.deps_from_containing = None
3078         # The set of symbols referenced by this comment (see
3079         # get_referenced_symbols())
3080         self.referenced_syms = set()
3081         # Like 'referenced_syms', but includes symbols from
3082         # dependencies inherited from enclosing menus and ifs
3083         self.all_referenced_syms = None
3084
3085         self.filename = None
3086         self.linenr = None
3087
3088     def _make_conf(self, append_fn):
3089         if self.config._eval_expr(self.dep_expr) != "n":
3090             append_fn("\n#\n# {0}\n#".format(self.text))
3091
3092 class Kconfig_Syntax_Error(Exception):
3093     """Exception raised for syntax errors."""
3094     pass
3095
3096 class Internal_Error(Exception):
3097     """Exception raised for internal errors."""
3098     pass
3099
3100 #
3101 # Public functions
3102 #
3103
3104 def tri_less(v1, v2):
3105     """Returns True if the tristate v1 is less than the tristate v2, where "n",
3106     "m" and "y" are ordered from lowest to highest."""
3107     return TRI_TO_INT[v1] < TRI_TO_INT[v2]
3108
3109 def tri_less_eq(v1, v2):
3110     """Returns True if the tristate v1 is less than or equal to the tristate
3111     v2, where "n", "m" and "y" are ordered from lowest to highest."""
3112     return TRI_TO_INT[v1] <= TRI_TO_INT[v2]
3113
3114 def tri_greater(v1, v2):
3115     """Returns True if the tristate v1 is greater than the tristate v2, where
3116     "n", "m" and "y" are ordered from lowest to highest."""
3117     return TRI_TO_INT[v1] > TRI_TO_INT[v2]
3118
3119 def tri_greater_eq(v1, v2):
3120     """Returns True if the tristate v1 is greater than or equal to the tristate
3121     v2, where "n", "m" and "y" are ordered from lowest to highest."""
3122     return TRI_TO_INT[v1] >= TRI_TO_INT[v2]
3123
3124 #
3125 # Internal classes
3126 #
3127
3128 class _Feed(object):
3129
3130     """Class for working with sequences in a stream-like fashion; handy for
3131     tokens."""
3132
3133     # This would be more helpful on the item classes, but would remove some
3134     # flexibility
3135     __slots__ = ['items', 'length', 'i']
3136
3137     def __init__(self, items):
3138         self.items = items
3139         self.length = len(self.items)
3140         self.i = 0
3141
3142     def get_next(self):
3143         if self.i >= self.length:
3144             return None
3145         item = self.items[self.i]
3146         self.i += 1
3147         return item
3148
3149     def peek_next(self):
3150         return None if self.i >= self.length else self.items[self.i]
3151
3152     def check(self, token):
3153         """Check if the next token is 'token'. If so, remove it from the token
3154         feed and return True. Otherwise, leave it in and return False."""
3155         if self.i < self.length and self.items[self.i] == token:
3156             self.i += 1
3157             return True
3158         return False
3159
3160     def unget_all(self):
3161         self.i = 0
3162
3163 class _FileFeed(object):
3164
3165     """Feeds lines from a file. Keeps track of the filename and current line
3166     number. Joins any line ending in \\ with the following line. We need to be
3167     careful to get the line number right in the presence of continuation
3168     lines."""
3169
3170     __slots__ = ['filename', 'lines', 'length', 'linenr']
3171
3172     def __init__(self, filename):
3173         self.filename = _clean_up_path(filename)
3174         with open(filename, "r") as f:
3175             # No interleaving of I/O and processing yet. Don't know if it would
3176             # help.
3177             self.lines = f.readlines()
3178         self.length = len(self.lines)
3179         self.linenr = 0
3180
3181     def get_next(self):
3182         if self.linenr >= self.length:
3183             return None
3184         line = self.lines[self.linenr]
3185         self.linenr += 1
3186         while line.endswith("\\\n"):
3187             line = line[:-2] + self.lines[self.linenr]
3188             self.linenr += 1
3189         return line
3190
3191     def peek_next(self):
3192         linenr = self.linenr
3193         if linenr >= self.length:
3194             return None
3195         line = self.lines[linenr]
3196         while line.endswith("\\\n"):
3197             linenr += 1
3198             line = line[:-2] + self.lines[linenr]
3199         return line
3200
3201     def unget(self):
3202         self.linenr -= 1
3203         while self.lines[self.linenr].endswith("\\\n"):
3204             self.linenr -= 1
3205
3206     def next_nonblank(self):
3207         """Removes lines up to and including the next non-blank (not all-space)
3208         line and returns it. Returns None if there are no more non-blank
3209         lines."""
3210         while 1:
3211             line = self.get_next()
3212             if line is None or not line.isspace():
3213                 return line
3214
3215 #
3216 # Internal functions
3217 #
3218
3219 def _get_visibility(sc):
3220     """Symbols and Choices have a "visibility" that acts as an upper bound on
3221     the values a user can set for them, corresponding to the visibility in e.g.
3222     'make menuconfig'. This function calculates the visibility for the Symbol
3223     or Choice 'sc' -- the logic is nearly identical."""
3224     if sc.cached_visibility is None:
3225         vis = "n"
3226         for _, cond_expr in sc.prompts:
3227             vis = sc.config._eval_max(vis, cond_expr)
3228
3229         if isinstance(sc, Symbol) and sc.is_choice_sym:
3230             if sc.type == TRISTATE and vis == "m" and \
3231                sc.parent.get_mode() == "y":
3232                 # Choice symbols with visibility "m" are not visible if the
3233                 # choice has mode "y"
3234                 vis = "n"
3235             else:
3236                 vis = sc.config._eval_min(vis, _get_visibility(sc.parent))
3237
3238         # Promote "m" to "y" if we're dealing with a non-tristate
3239         if vis == "m" and sc.type != TRISTATE:
3240             vis = "y"
3241
3242         sc.cached_visibility = vis
3243
3244     return sc.cached_visibility
3245
3246 def _make_and(e1, e2):
3247     """Constructs an AND (&&) expression. Performs trivial simplification.
3248     Nones equate to 'y'.
3249
3250     Note: returns None if e1 == e2 == None."""
3251     if e1 is None or e1 == "y":
3252         return e2
3253     if e2 is None or e2 == "y":
3254         return e1
3255
3256     # Prefer to merge argument lists if possible to reduce the number of nodes
3257
3258     if isinstance(e1, tuple) and e1[0] == AND:
3259         if isinstance(e2, tuple) and e2[0] == AND:
3260             return (AND, e1[1] + e2[1])
3261         return (AND, e1[1] + [e2])
3262
3263     if isinstance(e2, tuple) and e2[0] == AND:
3264         return (AND, e2[1] + [e1])
3265
3266     return (AND, [e1, e2])
3267
3268 def _make_or(e1, e2):
3269     """Constructs an OR (||) expression. Performs trivial simplification and
3270     avoids Nones. Nones equate to 'y', which is usually what we want, but needs
3271     to be kept in mind."""
3272
3273     # Perform trivial simplification and avoid None's (which
3274     # correspond to y's)
3275     if e1 is None or e2 is None or e1 == "y" or e2 == "y":
3276         return "y"
3277     if e1 == "n":
3278         return e2
3279
3280     # Prefer to merge argument lists if possible to reduce the number of nodes
3281
3282     if isinstance(e1, tuple) and e1[0] == OR:
3283         if isinstance(e2, tuple) and e2[0] == OR:
3284             return (OR, e1[1] + e2[1])
3285         return (OR, e1[1] + [e2])
3286
3287     if isinstance(e2, tuple) and e2[0] == OR:
3288         return (OR, e2[1] + [e1])
3289
3290     return (OR, [e1, e2])
3291
3292 def _get_expr_syms_rec(expr, res):
3293     """_get_expr_syms() helper. Recurses through expressions."""
3294     if isinstance(expr, Symbol):
3295         res.add(expr)
3296     elif isinstance(expr, str):
3297         return
3298     elif expr[0] == AND or expr[0] == OR:
3299         for term in expr[1]:
3300             _get_expr_syms_rec(term, res)
3301     elif expr[0] == NOT:
3302         _get_expr_syms_rec(expr[1], res)
3303     elif expr[0] == EQUAL or expr[0] == UNEQUAL:
3304         if isinstance(expr[1], Symbol):
3305             res.add(expr[1])
3306         if isinstance(expr[2], Symbol):
3307             res.add(expr[2])
3308     else:
3309         _internal_error("Internal error while fetching symbols from an "
3310                         "expression with token stream {0}.".format(expr))
3311
3312 def _get_expr_syms(expr):
3313     """Returns the set() of symbols appearing in expr."""
3314     res = set()
3315     if expr is not None:
3316         _get_expr_syms_rec(expr, res)
3317     return res
3318
3319 def _str_val(obj):
3320     """Returns the value of obj as a string. If obj is not a string (constant
3321     symbol), it must be a Symbol."""
3322     return obj if isinstance(obj, str) else obj.get_value()
3323
3324 def _make_block_conf(block, append_fn):
3325     """Returns a list of .config strings for a block (list) of items."""
3326
3327     # Collect the substrings in a list and later use join() instead of += to
3328     # build the final .config contents. With older Python versions, this yields
3329     # linear instead of quadratic complexity.
3330     for item in block:
3331         item._make_conf(append_fn)
3332
3333 def _sym_str_string(sym_or_str):
3334     if isinstance(sym_or_str, str):
3335         return '"' + sym_or_str + '"'
3336     return sym_or_str.name
3337
3338 def _intersperse(lst, op):
3339     """_expr_to_str() helper. Gets the string representation of each expression
3340     in lst and produces a list where op has been inserted between the
3341     elements."""
3342     if not lst:
3343         return ""
3344
3345     res = []
3346
3347     def handle_sub_expr(expr):
3348         no_parens = isinstance(expr, (str, Symbol)) or \
3349                     expr[0] in (EQUAL, UNEQUAL) or \
3350                     PRECEDENCE[op] <= PRECEDENCE[expr[0]]
3351         if not no_parens:
3352             res.append("(")
3353         res.extend(_expr_to_str_rec(expr))
3354         if not no_parens:
3355             res.append(")")
3356
3357     op_str = OP_TO_STR[op]
3358
3359     handle_sub_expr(lst[0])
3360     for expr in lst[1:]:
3361         res.append(op_str)
3362         handle_sub_expr(expr)
3363
3364     return res
3365
3366 def _expr_to_str_rec(expr):
3367     if expr is None:
3368         return [""]
3369
3370     if isinstance(expr, (Symbol, str)):
3371         return [_sym_str_string(expr)]
3372
3373     if expr[0] in (AND, OR):
3374         return _intersperse(expr[1], expr[0])
3375
3376     if expr[0] == NOT:
3377         need_parens = not isinstance(expr[1], (str, Symbol))
3378
3379         res = ["!"]
3380         if need_parens:
3381             res.append("(")
3382         res.extend(_expr_to_str_rec(expr[1]))
3383         if need_parens:
3384             res.append(")")
3385         return res
3386
3387     if expr[0] in (EQUAL, UNEQUAL):
3388         return [_sym_str_string(expr[1]),
3389                 OP_TO_STR[expr[0]],
3390                 _sym_str_string(expr[2])]
3391
3392 def _expr_to_str(expr):
3393     return "".join(_expr_to_str_rec(expr))
3394
3395 def _indentation(line):
3396     """Returns the length of the line's leading whitespace, treating tab stops
3397     as being spaced 8 characters apart."""
3398     line = line.expandtabs()
3399     return len(line) - len(line.lstrip())
3400
3401 def _deindent(line, indent):
3402     """Deindent 'line' by 'indent' spaces."""
3403     line = line.expandtabs()
3404     if len(line) <= indent:
3405         return line
3406     return line[indent:]
3407
3408 def _is_base_n(s, n):
3409     try:
3410         int(s, n)
3411         return True
3412     except ValueError:
3413         return False
3414
3415 def _lines(*args):
3416     """Returns a string consisting of all arguments, with newlines inserted
3417     between them."""
3418     return "\n".join(args)
3419
3420 def _comment(s):
3421     """Returns a new string with "#" inserted before each line in 's'."""
3422     if not s:
3423         return "#"
3424     res = "".join(["#" + line for line in s.splitlines(True)])
3425     if s.endswith("\n"):
3426         return res + "#"
3427     return res
3428
3429 def _clean_up_path(path):
3430     """Strips an initial "./" and any trailing slashes from 'path'."""
3431     if path.startswith("./"):
3432         path = path[2:]
3433     return path.rstrip("/")
3434
3435 def _build_msg(msg, filename, linenr):
3436     if filename is not None:
3437         msg = "{0}:{1}: ".format(_clean_up_path(filename), linenr) + msg
3438     return msg
3439
3440 def _stderr_msg(msg, filename, linenr):
3441     sys.stderr.write(_build_msg(msg, filename, linenr) + "\n")
3442
3443 def _tokenization_error(s, filename, linenr):
3444     loc = "" if filename is None else "{0}:{1}: ".format(filename, linenr)
3445     raise Kconfig_Syntax_Error("{0}Couldn't tokenize '{1}'"
3446                                .format(loc, s.strip()))
3447
3448 def _parse_error(s, msg, filename, linenr):
3449     loc = "" if filename is None else "{0}:{1}: ".format(filename, linenr)
3450     raise Kconfig_Syntax_Error("{0}Couldn't parse '{1}'{2}"
3451                                .format(loc, s.strip(),
3452                                        "." if msg is None else ": " + msg))
3453
3454 def _internal_error(msg):
3455     raise Internal_Error(msg +
3456       "\nSorry! You may want to send an email to ulfalizer a.t Google's "
3457       "email service to tell me about this. Include the message above and the "
3458       "stack trace and describe what you were doing.")
3459
3460 #
3461 # Internal global constants
3462 #
3463
3464 # Tokens
3465 (T_AND, T_OR, T_NOT,
3466  T_OPEN_PAREN, T_CLOSE_PAREN,
3467  T_EQUAL, T_UNEQUAL,
3468  T_MAINMENU, T_MENU, T_ENDMENU,
3469  T_SOURCE, T_CHOICE, T_ENDCHOICE,
3470  T_COMMENT, T_CONFIG, T_MENUCONFIG,
3471  T_HELP, T_IF, T_ENDIF, T_DEPENDS, T_ON,
3472  T_OPTIONAL, T_PROMPT, T_DEFAULT,
3473  T_BOOL, T_TRISTATE, T_HEX, T_INT, T_STRING,
3474  T_DEF_BOOL, T_DEF_TRISTATE,
3475  T_SELECT, T_IMPLY, T_RANGE, T_OPTION, T_ALLNOCONFIG_Y, T_ENV,
3476  T_DEFCONFIG_LIST, T_MODULES, T_VISIBLE) = range(40)
3477
3478 # The leading underscore before the function assignments below prevent pydoc
3479 # from listing them. The constants could be hidden too, but they're fairly
3480 # obviously internal anyway, so don't bother spamming the code.
3481
3482 # Keyword to token map. Note that the get() method is assigned directly as a
3483 # small optimization.
3484 _get_keyword = \
3485   {"mainmenu": T_MAINMENU, "menu": T_MENU, "endmenu": T_ENDMENU,
3486    "endif": T_ENDIF, "endchoice": T_ENDCHOICE, "source": T_SOURCE,
3487    "choice": T_CHOICE, "config": T_CONFIG, "comment": T_COMMENT,
3488    "menuconfig": T_MENUCONFIG, "help": T_HELP, "if": T_IF,
3489    "depends": T_DEPENDS, "on": T_ON, "optional": T_OPTIONAL,
3490    "prompt": T_PROMPT, "default": T_DEFAULT, "bool": T_BOOL, "boolean": T_BOOL,
3491    "tristate": T_TRISTATE, "int": T_INT, "hex": T_HEX, "def_bool": T_DEF_BOOL,
3492    "def_tristate": T_DEF_TRISTATE, "string": T_STRING, "select": T_SELECT,
3493    "imply" : T_IMPLY, "range": T_RANGE, "option": T_OPTION,
3494    "allnoconfig_y": T_ALLNOCONFIG_Y, "env": T_ENV,
3495    "defconfig_list": T_DEFCONFIG_LIST, "modules": T_MODULES,
3496    "visible": T_VISIBLE}.get
3497
3498 # Strings to use for True and False
3499 BOOL_STR = {False: "false", True: "true"}
3500
3501 # Tokens after which identifier-like lexemes are treated as strings. T_CHOICE
3502 # is included to avoid symbols being registered for named choices.
3503 STRING_LEX = frozenset((T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING, T_CHOICE,
3504                         T_PROMPT, T_MENU, T_COMMENT, T_SOURCE, T_MAINMENU))
3505
3506 # Matches the initial token on a line; see _tokenize(). Also eats trailing
3507 # whitespace as an optimization.
3508 _initial_token_re_match = re.compile(r"[^\w]*(\w+)\s*").match
3509
3510 # Matches an identifier/keyword optionally preceded by whitespace. Also eats
3511 # trailing whitespace as an optimization.
3512 _id_keyword_re_match = re.compile(r"\s*([\w./-]+)\s*").match
3513
3514 # Regular expression for finding $-references to symbols in strings
3515 _sym_ref_re_search = re.compile(r"\$[A-Za-z0-9_]+").search
3516
3517 # Integers representing symbol types
3518 UNKNOWN, BOOL, TRISTATE, STRING, HEX, INT = range(6)
3519
3520 # Strings to use for types
3521 TYPENAME = {UNKNOWN: "unknown", BOOL: "bool", TRISTATE: "tristate",
3522             STRING: "string", HEX: "hex", INT: "int"}
3523
3524 # Token to type mapping
3525 TOKEN_TO_TYPE = {T_BOOL: BOOL, T_TRISTATE: TRISTATE, T_STRING: STRING,
3526                  T_INT: INT, T_HEX: HEX}
3527
3528 # Default values for symbols of different types (the value the symbol gets if
3529 # it is not assigned a user value and none of its 'default' clauses kick in)
3530 DEFAULT_VALUE = {BOOL: "n", TRISTATE: "n", STRING: "", INT: "", HEX: ""}
3531
3532 # Indicates that no item is selected in a choice statement
3533 NO_SELECTION = 0
3534
3535 # Integers representing expression types
3536 AND, OR, NOT, EQUAL, UNEQUAL = range(5)
3537
3538 # Map from tristate values to integers
3539 TRI_TO_INT = {"n": 0, "m": 1, "y": 2}
3540
3541 # Printing-related stuff
3542
3543 OP_TO_STR = {AND: " && ", OR: " || ", EQUAL: " = ", UNEQUAL: " != "}
3544 PRECEDENCE = {OR: 0, AND: 1, NOT: 2}