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