xref: /nrf52832-nimble/rt-thread/tools/kconfiglib.py (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero# Copyright (c) 2011-2018, Ulf Magnusson
2*10465441SEvalZero# SPDX-License-Identifier: ISC
3*10465441SEvalZero
4*10465441SEvalZero"""
5*10465441SEvalZeroOverview
6*10465441SEvalZero========
7*10465441SEvalZero
8*10465441SEvalZeroKconfiglib is a Python 2/3 library for scripting and extracting information
9*10465441SEvalZerofrom Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt)
10*10465441SEvalZeroconfiguration systems.
11*10465441SEvalZero
12*10465441SEvalZeroSee the homepage at https://github.com/ulfalizer/Kconfiglib for a longer
13*10465441SEvalZerooverview.
14*10465441SEvalZero
15*10465441SEvalZeroUsing Kconfiglib on the Linux kernel with the Makefile targets
16*10465441SEvalZero==============================================================
17*10465441SEvalZero
18*10465441SEvalZeroFor the Linux kernel, a handy interface is provided by the
19*10465441SEvalZeroscripts/kconfig/Makefile patch, which can be applied with either 'git am' or
20*10465441SEvalZerothe 'patch' utility:
21*10465441SEvalZero
22*10465441SEvalZero  $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am
23*10465441SEvalZero  $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1
24*10465441SEvalZero
25*10465441SEvalZeroWarning: Not passing -p1 to patch will cause the wrong file to be patched.
26*10465441SEvalZero
27*10465441SEvalZeroPlease tell me if the patch does not apply. It should be trivial to apply
28*10465441SEvalZeromanually, as it's just a block of text that needs to be inserted near the other
29*10465441SEvalZero*conf: targets in scripts/kconfig/Makefile.
30*10465441SEvalZero
31*10465441SEvalZeroLook further down for a motivation for the Makefile patch and for instructions
32*10465441SEvalZeroon how you can use Kconfiglib without it.
33*10465441SEvalZero
34*10465441SEvalZeroIf you do not wish to install Kconfiglib via pip, the Makefile patch is set up
35*10465441SEvalZeroso that you can also just clone Kconfiglib into the kernel root:
36*10465441SEvalZero
37*10465441SEvalZero  $ git clone git://github.com/ulfalizer/Kconfiglib.git
38*10465441SEvalZero  $ git am Kconfiglib/makefile.patch  (or 'patch -p1 < Kconfiglib/makefile.patch')
39*10465441SEvalZero
40*10465441SEvalZeroWarning: The directory name Kconfiglib/ is significant in this case, because
41*10465441SEvalZeroit's added to PYTHONPATH by the new targets in makefile.patch.
42*10465441SEvalZero
43*10465441SEvalZeroThe targets added by the Makefile patch are described in the following
44*10465441SEvalZerosections.
45*10465441SEvalZero
46*10465441SEvalZero
47*10465441SEvalZeromake [ARCH=<arch>] iscriptconfig
48*10465441SEvalZero--------------------------------
49*10465441SEvalZero
50*10465441SEvalZeroThis target gives an interactive Python prompt where a Kconfig instance has
51*10465441SEvalZerobeen preloaded and is available in 'kconf'. To change the Python interpreter
52*10465441SEvalZeroused, pass PYTHONCMD=<executable> to make. The default is "python".
53*10465441SEvalZero
54*10465441SEvalZeroTo get a feel for the API, try evaluating and printing the symbols in
55*10465441SEvalZerokconf.defined_syms, and explore the MenuNode menu tree starting at
56*10465441SEvalZerokconf.top_node by following 'next' and 'list' pointers.
57*10465441SEvalZero
58*10465441SEvalZeroThe item contained in a menu node is found in MenuNode.item (note that this can
59*10465441SEvalZerobe one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all
60*10465441SEvalZerosymbols and choices have a 'nodes' attribute containing their menu nodes
61*10465441SEvalZero(usually only one). Printing a menu node will print its item, in Kconfig
62*10465441SEvalZeroformat.
63*10465441SEvalZero
64*10465441SEvalZeroIf you want to look up a symbol by name, use the kconf.syms dictionary.
65*10465441SEvalZero
66*10465441SEvalZero
67*10465441SEvalZeromake scriptconfig SCRIPT=<script> [SCRIPT_ARG=<arg>]
68*10465441SEvalZero----------------------------------------------------
69*10465441SEvalZero
70*10465441SEvalZeroThis target runs the Python script given by the SCRIPT parameter on the
71*10465441SEvalZeroconfiguration. sys.argv[1] holds the name of the top-level Kconfig file
72*10465441SEvalZero(currently always "Kconfig" in practice), and sys.argv[2] holds the SCRIPT_ARG
73*10465441SEvalZeroargument, if given.
74*10465441SEvalZero
75*10465441SEvalZeroSee the examples/ subdirectory for example scripts.
76*10465441SEvalZero
77*10465441SEvalZero
78*10465441SEvalZeroUsing Kconfiglib without the Makefile targets
79*10465441SEvalZero=============================================
80*10465441SEvalZero
81*10465441SEvalZeroThe make targets are only needed to pick up environment variables exported from
82*10465441SEvalZerothe Kbuild makefiles and referenced inside Kconfig files, via e.g.
83*10465441SEvalZero'source "arch/$(SRCARCH)/Kconfig" and '$(shell,...)'.
84*10465441SEvalZero
85*10465441SEvalZeroThese variables are referenced as of writing (Linux 4.18), together with sample
86*10465441SEvalZerovalues:
87*10465441SEvalZero
88*10465441SEvalZero  srctree          (.)
89*10465441SEvalZero  ARCH             (x86)
90*10465441SEvalZero  SRCARCH          (x86)
91*10465441SEvalZero  KERNELVERSION    (4.18.0)
92*10465441SEvalZero  CC               (gcc)
93*10465441SEvalZero  HOSTCC           (gcc)
94*10465441SEvalZero  HOSTCXX          (g++)
95*10465441SEvalZero  CC_VERSION_TEXT  (gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0)
96*10465441SEvalZero
97*10465441SEvalZeroTo run Kconfiglib without the Makefile patch, set the environment variables
98*10465441SEvalZeromanually:
99*10465441SEvalZero
100*10465441SEvalZero  $ srctree=. ARCH=x86 SRCARCH=x86 KERNELVERSION=`make kernelversion` ... python(3)
101*10465441SEvalZero  >>> import kconfiglib
102*10465441SEvalZero  >>> kconf = kconfiglib.Kconfig()  # filename defaults to "Kconfig"
103*10465441SEvalZero
104*10465441SEvalZeroSearch the top-level Makefile for "Additional ARCH settings" to see other
105*10465441SEvalZeropossibilities for ARCH and SRCARCH.
106*10465441SEvalZero
107*10465441SEvalZeroTo see a list of all referenced environment variables together with their
108*10465441SEvalZerovalues, run this code from e.g. 'make iscriptconfig':
109*10465441SEvalZero
110*10465441SEvalZero  import os
111*10465441SEvalZero  for var in kconf.env_vars:
112*10465441SEvalZero      print(var, os.environ[var])
113*10465441SEvalZero
114*10465441SEvalZero
115*10465441SEvalZeroIntro to symbol values
116*10465441SEvalZero======================
117*10465441SEvalZero
118*10465441SEvalZeroKconfiglib has the same assignment semantics as the C implementation.
119*10465441SEvalZero
120*10465441SEvalZeroAny symbol can be assigned a value by the user (via Kconfig.load_config() or
121*10465441SEvalZeroSymbol.set_value()), but this user value is only respected if the symbol is
122*10465441SEvalZerovisible, which corresponds to it (currently) being visible in the menuconfig
123*10465441SEvalZerointerface.
124*10465441SEvalZero
125*10465441SEvalZeroFor symbols with prompts, the visibility of the symbol is determined by the
126*10465441SEvalZerocondition on the prompt. Symbols without prompts are never visible, so setting
127*10465441SEvalZeroa user value on them is pointless. A warning will be printed by default if
128*10465441SEvalZeroSymbol.set_value() is called on a promptless symbol. Assignments to promptless
129*10465441SEvalZerosymbols are normal within a .config file, so no similar warning will be printed
130*10465441SEvalZeroby load_config().
131*10465441SEvalZero
132*10465441SEvalZeroDependencies from parents and 'if'/'depends on' are propagated to properties,
133*10465441SEvalZeroincluding prompts, so these two configurations are logically equivalent:
134*10465441SEvalZero
135*10465441SEvalZero(1)
136*10465441SEvalZero
137*10465441SEvalZero  menu "menu"
138*10465441SEvalZero  depends on A
139*10465441SEvalZero
140*10465441SEvalZero  if B
141*10465441SEvalZero
142*10465441SEvalZero  config FOO
143*10465441SEvalZero      tristate "foo" if D
144*10465441SEvalZero      default y
145*10465441SEvalZero      depends on C
146*10465441SEvalZero
147*10465441SEvalZero  endif
148*10465441SEvalZero
149*10465441SEvalZero  endmenu
150*10465441SEvalZero
151*10465441SEvalZero(2)
152*10465441SEvalZero
153*10465441SEvalZero  menu "menu"
154*10465441SEvalZero  depends on A
155*10465441SEvalZero
156*10465441SEvalZero  config FOO
157*10465441SEvalZero      tristate "foo" if A && B && C && D
158*10465441SEvalZero      default y if A && B && C
159*10465441SEvalZero
160*10465441SEvalZero  endmenu
161*10465441SEvalZero
162*10465441SEvalZeroIn this example, A && B && C && D (the prompt condition) needs to be non-n for
163*10465441SEvalZeroFOO to be visible (assignable). If its value is m, the symbol can only be
164*10465441SEvalZeroassigned the value m: The visibility sets an upper bound on the value that can
165*10465441SEvalZerobe assigned by the user, and any higher user value will be truncated down.
166*10465441SEvalZero
167*10465441SEvalZero'default' properties are independent of the visibility, though a 'default' will
168*10465441SEvalZerooften get the same condition as the prompt due to dependency propagation.
169*10465441SEvalZero'default' properties are used if the symbol is not visible or has no user
170*10465441SEvalZerovalue.
171*10465441SEvalZero
172*10465441SEvalZeroSymbols with no user value (or that have a user value but are not visible) and
173*10465441SEvalZerono (active) 'default' default to n for bool/tristate symbols, and to the empty
174*10465441SEvalZerostring for other symbol types.
175*10465441SEvalZero
176*10465441SEvalZero'select' works similarly to symbol visibility, but sets a lower bound on the
177*10465441SEvalZerovalue of the symbol. The lower bound is determined by the value of the
178*10465441SEvalZeroselect*ing* symbol. 'select' does not respect visibility, so non-visible
179*10465441SEvalZerosymbols can be forced to a particular (minimum) value by a select as well.
180*10465441SEvalZero
181*10465441SEvalZeroFor non-bool/tristate symbols, it only matters whether the visibility is n or
182*10465441SEvalZeronon-n: m visibility acts the same as y visibility.
183*10465441SEvalZero
184*10465441SEvalZeroConditions on 'default' and 'select' work in mostly intuitive ways. If the
185*10465441SEvalZerocondition is n, the 'default' or 'select' is disabled. If it is m, the
186*10465441SEvalZero'default' or 'select' value (the value of the selecting symbol) is truncated
187*10465441SEvalZerodown to m.
188*10465441SEvalZero
189*10465441SEvalZeroWhen writing a configuration with Kconfig.write_config(), only symbols that are
190*10465441SEvalZerovisible, have an (active) default, or are selected will get written out (note
191*10465441SEvalZerothat this includes all symbols that would accept user values). Kconfiglib
192*10465441SEvalZeromatches the .config format produced by the C implementations down to the
193*10465441SEvalZerocharacter. This eases testing.
194*10465441SEvalZero
195*10465441SEvalZeroFor a visible bool/tristate symbol FOO with value n, this line is written to
196*10465441SEvalZero.config:
197*10465441SEvalZero
198*10465441SEvalZero    # CONFIG_FOO is not set
199*10465441SEvalZero
200*10465441SEvalZeroThe point is to remember the user n selection (which might differ from the
201*10465441SEvalZerodefault value the symbol would get), while at the same sticking to the rule
202*10465441SEvalZerothat undefined corresponds to n (.config uses Makefile format, making the line
203*10465441SEvalZeroabove a comment). When the .config file is read back in, this line will be
204*10465441SEvalZerotreated the same as the following assignment:
205*10465441SEvalZero
206*10465441SEvalZero    CONFIG_FOO=n
207*10465441SEvalZero
208*10465441SEvalZeroIn Kconfiglib, the set of (currently) assignable values for a bool/tristate
209*10465441SEvalZerosymbol appear in Symbol.assignable. For other symbol types, just check if
210*10465441SEvalZerosym.visibility is non-0 (non-n) to see whether the user value will have an
211*10465441SEvalZeroeffect.
212*10465441SEvalZero
213*10465441SEvalZero
214*10465441SEvalZeroIntro to the menu tree
215*10465441SEvalZero======================
216*10465441SEvalZero
217*10465441SEvalZeroThe menu structure, as seen in e.g. menuconfig, is represented by a tree of
218*10465441SEvalZeroMenuNode objects. The top node of the configuration corresponds to an implicit
219*10465441SEvalZerotop-level menu, the title of which is shown at the top in the standard
220*10465441SEvalZeromenuconfig interface. (The title is also available in Kconfig.mainmenu_text in
221*10465441SEvalZeroKconfiglib.)
222*10465441SEvalZero
223*10465441SEvalZeroThe top node is found in Kconfig.top_node. From there, you can visit child menu
224*10465441SEvalZeronodes by following the 'list' pointer, and any following menu nodes by
225*10465441SEvalZerofollowing the 'next' pointer. Usually, a non-None 'list' pointer indicates a
226*10465441SEvalZeromenu or Choice, but menu nodes for symbols can sometimes have a non-None 'list'
227*10465441SEvalZeropointer too due to submenus created implicitly from dependencies.
228*10465441SEvalZero
229*10465441SEvalZeroMenuNode.item is either a Symbol or a Choice object, or one of the constants
230*10465441SEvalZeroMENU and COMMENT. The prompt of the menu node can be found in MenuNode.prompt,
231*10465441SEvalZerowhich also holds the title for menus and comments. For Symbol and Choice,
232*10465441SEvalZeroMenuNode.help holds the help text (if any, otherwise None).
233*10465441SEvalZero
234*10465441SEvalZeroMost symbols will only have a single menu node. A symbol defined in multiple
235*10465441SEvalZerolocations will have one menu node for each location. The list of menu nodes for
236*10465441SEvalZeroa Symbol or Choice can be found in the Symbol/Choice.nodes attribute.
237*10465441SEvalZero
238*10465441SEvalZeroNote that prompts and help texts for symbols and choices are stored in their
239*10465441SEvalZeromenu node(s) rather than in the Symbol or Choice objects themselves. This makes
240*10465441SEvalZeroit possible to define a symbol in multiple locations with a different prompt or
241*10465441SEvalZerohelp text in each location. To get the help text or prompt for a symbol with a
242*10465441SEvalZerosingle menu node, do sym.nodes[0].help and sym.nodes[0].prompt, respectively.
243*10465441SEvalZeroThe prompt is a (text, condition) tuple, where condition determines the
244*10465441SEvalZerovisibility (see 'Intro to expressions' below).
245*10465441SEvalZero
246*10465441SEvalZeroThis organization mirrors the C implementation. MenuNode is called
247*10465441SEvalZero'struct menu' there, but I thought "menu" was a confusing name.
248*10465441SEvalZero
249*10465441SEvalZeroIt is possible to give a Choice a name and define it in multiple locations,
250*10465441SEvalZerohence why Choice.nodes is also a list.
251*10465441SEvalZero
252*10465441SEvalZeroAs a convenience, the properties added at a particular definition location are
253*10465441SEvalZeroavailable on the MenuNode itself, in e.g. MenuNode.defaults. This is helpful
254*10465441SEvalZerowhen generating documentation, so that symbols/choices defined in multiple
255*10465441SEvalZerolocations can be shown with the correct properties at each location.
256*10465441SEvalZero
257*10465441SEvalZero
258*10465441SEvalZeroIntro to expressions
259*10465441SEvalZero====================
260*10465441SEvalZero
261*10465441SEvalZeroExpressions can be evaluated with the expr_value() function and printed with
262*10465441SEvalZerothe expr_str() function (these are used internally as well). Evaluating an
263*10465441SEvalZeroexpression always yields a tristate value, where n, m, and y are represented as
264*10465441SEvalZero0, 1, and 2, respectively.
265*10465441SEvalZero
266*10465441SEvalZeroThe following table should help you figure out how expressions are represented.
267*10465441SEvalZeroA, B, C, ... are symbols (Symbol instances), NOT is the kconfiglib.NOT
268*10465441SEvalZeroconstant, etc.
269*10465441SEvalZero
270*10465441SEvalZeroExpression            Representation
271*10465441SEvalZero----------            --------------
272*10465441SEvalZeroA                     A
273*10465441SEvalZero"A"                   A (constant symbol)
274*10465441SEvalZero!A                    (NOT, A)
275*10465441SEvalZeroA && B                (AND, A, B)
276*10465441SEvalZeroA && B && C           (AND, A, (AND, B, C))
277*10465441SEvalZeroA || B                (OR, A, B)
278*10465441SEvalZeroA || (B && C && D)    (OR, A, (AND, B, (AND, C, D)))
279*10465441SEvalZeroA = B                 (EQUAL, A, B)
280*10465441SEvalZeroA != "foo"            (UNEQUAL, A, foo (constant symbol))
281*10465441SEvalZeroA && B = C && D       (AND, A, (AND, (EQUAL, B, C), D))
282*10465441SEvalZeron                     Kconfig.n (constant symbol)
283*10465441SEvalZerom                     Kconfig.m (constant symbol)
284*10465441SEvalZeroy                     Kconfig.y (constant symbol)
285*10465441SEvalZero"y"                   Kconfig.y (constant symbol)
286*10465441SEvalZero
287*10465441SEvalZeroStrings like "foo" in 'default "foo"' or 'depends on SYM = "foo"' are
288*10465441SEvalZerorepresented as constant symbols, so the only values that appear in expressions
289*10465441SEvalZeroare symbols***. This mirrors the C implementation.
290*10465441SEvalZero
291*10465441SEvalZero***For choice symbols, the parent Choice will appear in expressions as well,
292*10465441SEvalZerobut it's usually invisible as the value interfaces of Symbol and Choice are
293*10465441SEvalZeroidentical. This mirrors the C implementation and makes different choice modes
294*10465441SEvalZero"just work".
295*10465441SEvalZero
296*10465441SEvalZeroManual evaluation examples:
297*10465441SEvalZero
298*10465441SEvalZero  - The value of A && B is min(A.tri_value, B.tri_value)
299*10465441SEvalZero
300*10465441SEvalZero  - The value of A || B is max(A.tri_value, B.tri_value)
301*10465441SEvalZero
302*10465441SEvalZero  - The value of !A is 2 - A.tri_value
303*10465441SEvalZero
304*10465441SEvalZero  - The value of A = B is 2 (y) if A.str_value == B.str_value, and 0 (n)
305*10465441SEvalZero    otherwise. Note that str_value is used here instead of tri_value.
306*10465441SEvalZero
307*10465441SEvalZero    For constant (as well as undefined) symbols, str_value matches the name of
308*10465441SEvalZero    the symbol. This mirrors the C implementation and explains why
309*10465441SEvalZero    'depends on SYM = "foo"' above works as expected.
310*10465441SEvalZero
311*10465441SEvalZeron/m/y are automatically converted to the corresponding constant symbols
312*10465441SEvalZero"n"/"m"/"y" (Kconfig.n/m/y) during parsing.
313*10465441SEvalZero
314*10465441SEvalZeroKconfig.const_syms is a dictionary like Kconfig.syms but for constant symbols.
315*10465441SEvalZero
316*10465441SEvalZeroIf a condition is missing (e.g., <cond> when the 'if <cond>' is removed from
317*10465441SEvalZero'default A if <cond>'), it is actually Kconfig.y. The standard __str__()
318*10465441SEvalZerofunctions just avoid printing 'if y' conditions to give cleaner output.
319*10465441SEvalZero
320*10465441SEvalZero
321*10465441SEvalZeroKconfig extensions
322*10465441SEvalZero==================
323*10465441SEvalZero
324*10465441SEvalZeroKconfiglib implements two Kconfig extensions related to 'source':
325*10465441SEvalZero
326*10465441SEvalZero'source' with relative path
327*10465441SEvalZero---------------------------
328*10465441SEvalZero
329*10465441SEvalZeroKconfiglib supports a custom 'rsource' statement that sources Kconfig files
330*10465441SEvalZerowith a path relative to directory of the Kconfig file containing the 'rsource'
331*10465441SEvalZerostatement, instead of relative to the project root. This extension is not
332*10465441SEvalZerosupported by Linux kernel tools as of writing.
333*10465441SEvalZero
334*10465441SEvalZeroConsider following directory tree:
335*10465441SEvalZero
336*10465441SEvalZero  Project
337*10465441SEvalZero  +--Kconfig
338*10465441SEvalZero  |
339*10465441SEvalZero  +--src
340*10465441SEvalZero     +--Kconfig
341*10465441SEvalZero     |
342*10465441SEvalZero     +--SubSystem1
343*10465441SEvalZero        +--Kconfig
344*10465441SEvalZero        |
345*10465441SEvalZero        +--ModuleA
346*10465441SEvalZero           +--Kconfig
347*10465441SEvalZero
348*10465441SEvalZeroIn this example, assume that src/SubSystem1/Kconfig wants to source
349*10465441SEvalZerosrc/SubSystem1/ModuleA/Kconfig.
350*10465441SEvalZero
351*10465441SEvalZeroWith 'source', the following statement would be used:
352*10465441SEvalZero
353*10465441SEvalZero  source "src/SubSystem1/ModuleA/Kconfig"
354*10465441SEvalZero
355*10465441SEvalZeroUsing 'rsource', it can be rewritten as:
356*10465441SEvalZero
357*10465441SEvalZero  rsource "ModuleA/Kconfig"
358*10465441SEvalZero
359*10465441SEvalZeroIf an absolute path is given to 'rsource', it acts the same as 'source'.
360*10465441SEvalZero
361*10465441SEvalZero'rsource' can be used to create "position-independent" Kconfig trees that can
362*10465441SEvalZerobe moved around freely.
363*10465441SEvalZero
364*10465441SEvalZero
365*10465441SEvalZeroGlobbed sourcing
366*10465441SEvalZero----------------
367*10465441SEvalZero
368*10465441SEvalZero'source' and 'rsource' accept glob patterns, sourcing all matching Kconfig
369*10465441SEvalZerofiles. They require at least one matching file, throwing a KconfigError
370*10465441SEvalZerootherwise.
371*10465441SEvalZero
372*10465441SEvalZeroFor example, the following statement might source sub1/foofoofoo and
373*10465441SEvalZerosub2/foobarfoo:
374*10465441SEvalZero
375*10465441SEvalZero  source "sub[12]/foo*foo"
376*10465441SEvalZero
377*10465441SEvalZeroThe glob patterns accepted are the same as for the standard glob.glob()
378*10465441SEvalZerofunction.
379*10465441SEvalZero
380*10465441SEvalZeroTwo additional statements are provided for cases where it's acceptable for a
381*10465441SEvalZeropattern to match no files: 'osource' and 'orsource' (the o is for "optional").
382*10465441SEvalZero
383*10465441SEvalZeroFor example, the following statements will be no-ops if neither "foo" nor any
384*10465441SEvalZerofiles matching "bar*" exist:
385*10465441SEvalZero
386*10465441SEvalZero  osource "foo"
387*10465441SEvalZero  osource "bar*"
388*10465441SEvalZero
389*10465441SEvalZero'orsource' does a relative optional source.
390*10465441SEvalZero
391*10465441SEvalZero'source' and 'osource' are analogous to 'include' and '-include' in Make.
392*10465441SEvalZero
393*10465441SEvalZero
394*10465441SEvalZeroFeedback
395*10465441SEvalZero========
396*10465441SEvalZero
397*10465441SEvalZeroSend bug reports, suggestions, and questions to ulfalizer a.t Google's email
398*10465441SEvalZeroservice, or open a ticket on the GitHub page.
399*10465441SEvalZero"""
400*10465441SEvalZeroimport errno
401*10465441SEvalZeroimport glob
402*10465441SEvalZeroimport os
403*10465441SEvalZeroimport platform
404*10465441SEvalZeroimport re
405*10465441SEvalZeroimport subprocess
406*10465441SEvalZeroimport sys
407*10465441SEvalZeroimport textwrap
408*10465441SEvalZero
409*10465441SEvalZero# File layout:
410*10465441SEvalZero#
411*10465441SEvalZero# Public classes
412*10465441SEvalZero# Public functions
413*10465441SEvalZero# Internal functions
414*10465441SEvalZero# Public global constants
415*10465441SEvalZero# Internal global constants
416*10465441SEvalZero
417*10465441SEvalZero# Line length: 79 columns
418*10465441SEvalZero
419*10465441SEvalZero#
420*10465441SEvalZero# Public classes
421*10465441SEvalZero#
422*10465441SEvalZero
423*10465441SEvalZeroclass Kconfig(object):
424*10465441SEvalZero    """
425*10465441SEvalZero    Represents a Kconfig configuration, e.g. for x86 or ARM. This is the set of
426*10465441SEvalZero    symbols, choices, and menu nodes appearing in the configuration. Creating
427*10465441SEvalZero    any number of Kconfig objects (including for different architectures) is
428*10465441SEvalZero    safe. Kconfiglib doesn't keep any global state.
429*10465441SEvalZero
430*10465441SEvalZero    The following attributes are available. They should be treated as
431*10465441SEvalZero    read-only, and some are implemented through @property magic.
432*10465441SEvalZero
433*10465441SEvalZero    syms:
434*10465441SEvalZero      A dictionary with all symbols in the configuration, indexed by name. Also
435*10465441SEvalZero      includes all symbols that are referenced in expressions but never
436*10465441SEvalZero      defined, except for constant (quoted) symbols.
437*10465441SEvalZero
438*10465441SEvalZero      Undefined symbols can be recognized by Symbol.nodes being empty -- see
439*10465441SEvalZero      the 'Intro to the menu tree' section in the module docstring.
440*10465441SEvalZero
441*10465441SEvalZero    const_syms:
442*10465441SEvalZero      A dictionary like 'syms' for constant (quoted) symbols
443*10465441SEvalZero
444*10465441SEvalZero    named_choices:
445*10465441SEvalZero      A dictionary like 'syms' for named choices (choice FOO)
446*10465441SEvalZero
447*10465441SEvalZero    defined_syms:
448*10465441SEvalZero      A list with all defined symbols, in the same order as they appear in the
449*10465441SEvalZero      Kconfig files. Symbols defined in multiple locations appear multiple
450*10465441SEvalZero      times.
451*10465441SEvalZero
452*10465441SEvalZero      Note: You probably want to use 'unique_defined_syms' instead. This
453*10465441SEvalZero      attribute is mostly maintained for backwards compatibility.
454*10465441SEvalZero
455*10465441SEvalZero    unique_defined_syms:
456*10465441SEvalZero      A list like 'defined_syms', but with duplicates removed. Just the first
457*10465441SEvalZero      instance is kept for symbols defined in multiple locations. Kconfig order
458*10465441SEvalZero      is preserved otherwise.
459*10465441SEvalZero
460*10465441SEvalZero      Using this attribute instead of 'defined_syms' can save work, and
461*10465441SEvalZero      automatically gives reasonable behavior when writing configuration output
462*10465441SEvalZero      (symbols defined in multiple locations only generate output once, while
463*10465441SEvalZero      still preserving Kconfig order for readability).
464*10465441SEvalZero
465*10465441SEvalZero    choices:
466*10465441SEvalZero      A list with all choices, in the same order as they appear in the Kconfig
467*10465441SEvalZero      files.
468*10465441SEvalZero
469*10465441SEvalZero      Note: You probably want to use 'unique_choices' instead. This attribute
470*10465441SEvalZero      is mostly maintained for backwards compatibility.
471*10465441SEvalZero
472*10465441SEvalZero    unique_choices:
473*10465441SEvalZero      Analogous to 'unique_defined_syms', for choices. Named choices can have
474*10465441SEvalZero      multiple definition locations.
475*10465441SEvalZero
476*10465441SEvalZero    menus:
477*10465441SEvalZero      A list with all menus, in the same order as they appear in the Kconfig
478*10465441SEvalZero      files
479*10465441SEvalZero
480*10465441SEvalZero    comments:
481*10465441SEvalZero      A list with all comments, in the same order as they appear in the Kconfig
482*10465441SEvalZero      files
483*10465441SEvalZero
484*10465441SEvalZero    kconfig_filenames:
485*10465441SEvalZero      A list with the filenames of all Kconfig files included in the
486*10465441SEvalZero      configuration, relative to $srctree (or relative to the current directory
487*10465441SEvalZero      if $srctree isn't set).
488*10465441SEvalZero
489*10465441SEvalZero      The files are listed in the order they are source'd, starting with the
490*10465441SEvalZero      top-level Kconfig file. If a file is source'd multiple times, it will
491*10465441SEvalZero      appear multiple times. Use set() to get unique filenames.
492*10465441SEvalZero
493*10465441SEvalZero      Note: Using this for incremental builds is redundant. Kconfig.sync_deps()
494*10465441SEvalZero      already indirectly catches any file modifications that change the
495*10465441SEvalZero      configuration output.
496*10465441SEvalZero
497*10465441SEvalZero    env_vars:
498*10465441SEvalZero      A set() with the names of all environment variables referenced in the
499*10465441SEvalZero      Kconfig files.
500*10465441SEvalZero
501*10465441SEvalZero      Only environment variables referenced with the preprocessor $(FOO) syntax
502*10465441SEvalZero      will be registered. The older $FOO syntax is only supported for backwards
503*10465441SEvalZero      compatibility.
504*10465441SEvalZero
505*10465441SEvalZero      Also note that $(FOO) won't be registered unless the environment variable
506*10465441SEvalZero      $FOO is actually set. If it isn't, $(FOO) is an expansion of an unset
507*10465441SEvalZero      preprocessor variable (which gives the empty string).
508*10465441SEvalZero
509*10465441SEvalZero      Another gotcha is that environment variables referenced in the values of
510*10465441SEvalZero      recursively expanded preprocessor variables (those defined with =) will
511*10465441SEvalZero      only be registered if the variable is actually used (expanded) somewhere.
512*10465441SEvalZero
513*10465441SEvalZero      The note from the 'kconfig_filenames' documentation applies here too.
514*10465441SEvalZero
515*10465441SEvalZero    n/m/y:
516*10465441SEvalZero      The predefined constant symbols n/m/y. Also available in const_syms.
517*10465441SEvalZero
518*10465441SEvalZero    modules:
519*10465441SEvalZero      The Symbol instance for the modules symbol. Currently hardcoded to
520*10465441SEvalZero      MODULES, which is backwards compatible. Kconfiglib will warn if
521*10465441SEvalZero      'option modules' is set on some other symbol. Tell me if you need proper
522*10465441SEvalZero      'option modules' support.
523*10465441SEvalZero
524*10465441SEvalZero      'modules' is never None. If the MODULES symbol is not explicitly defined,
525*10465441SEvalZero      its tri_value will be 0 (n), as expected.
526*10465441SEvalZero
527*10465441SEvalZero      A simple way to enable modules is to do 'kconf.modules.set_value(2)'
528*10465441SEvalZero      (provided the MODULES symbol is defined and visible). Modules are
529*10465441SEvalZero      disabled by default in the kernel Kconfig files as of writing, though
530*10465441SEvalZero      nearly all defconfig files enable them (with 'CONFIG_MODULES=y').
531*10465441SEvalZero
532*10465441SEvalZero    defconfig_list:
533*10465441SEvalZero      The Symbol instance for the 'option defconfig_list' symbol, or None if no
534*10465441SEvalZero      defconfig_list symbol exists. The defconfig filename derived from this
535*10465441SEvalZero      symbol can be found in Kconfig.defconfig_filename.
536*10465441SEvalZero
537*10465441SEvalZero    defconfig_filename:
538*10465441SEvalZero      The filename given by the defconfig_list symbol. This is taken from the
539*10465441SEvalZero      first 'default' with a satisfied condition where the specified file
540*10465441SEvalZero      exists (can be opened for reading). If a defconfig file foo/defconfig is
541*10465441SEvalZero      not found and $srctree was set when the Kconfig was created,
542*10465441SEvalZero      $srctree/foo/defconfig is looked up as well.
543*10465441SEvalZero
544*10465441SEvalZero      'defconfig_filename' is None if either no defconfig_list symbol exists,
545*10465441SEvalZero      or if the defconfig_list symbol has no 'default' with a satisfied
546*10465441SEvalZero      condition that specifies a file that exists.
547*10465441SEvalZero
548*10465441SEvalZero      Gotcha: scripts/kconfig/Makefile might pass --defconfig=<defconfig> to
549*10465441SEvalZero      scripts/kconfig/conf when running e.g. 'make defconfig'. This option
550*10465441SEvalZero      overrides the defconfig_list symbol, meaning defconfig_filename might not
551*10465441SEvalZero      always match what 'make defconfig' would use.
552*10465441SEvalZero
553*10465441SEvalZero    top_node:
554*10465441SEvalZero      The menu node (see the MenuNode class) of the implicit top-level menu.
555*10465441SEvalZero      Acts as the root of the menu tree.
556*10465441SEvalZero
557*10465441SEvalZero    mainmenu_text:
558*10465441SEvalZero      The prompt (title) of the top menu (top_node). Defaults to "Main menu".
559*10465441SEvalZero      Can be changed with the 'mainmenu' statement (see kconfig-language.txt).
560*10465441SEvalZero
561*10465441SEvalZero    variables:
562*10465441SEvalZero      A dictionary with all preprocessor variables, indexed by name. See the
563*10465441SEvalZero      Variable class.
564*10465441SEvalZero
565*10465441SEvalZero    warnings:
566*10465441SEvalZero      A list of strings containing all warnings that have been generated. This
567*10465441SEvalZero      allows flexibility in how warnings are printed and processed.
568*10465441SEvalZero
569*10465441SEvalZero      See the 'warn_to_stderr' parameter to Kconfig.__init__() and the
570*10465441SEvalZero      Kconfig.enable/disable_stderr_warnings() functions as well. Note that
571*10465441SEvalZero      warnings still get added to Kconfig.warnings when 'warn_to_stderr' is
572*10465441SEvalZero      True.
573*10465441SEvalZero
574*10465441SEvalZero      Just as for warnings printed to stderr, only optional warnings that are
575*10465441SEvalZero      enabled will get added to Kconfig.warnings. See the various
576*10465441SEvalZero      Kconfig.enable/disable_*_warnings() functions.
577*10465441SEvalZero
578*10465441SEvalZero    srctree:
579*10465441SEvalZero      The value of the $srctree environment variable when the configuration was
580*10465441SEvalZero      loaded, or the empty string if $srctree wasn't set. This gives nice
581*10465441SEvalZero      behavior with os.path.join(), which treats "" as the current directory,
582*10465441SEvalZero      without adding "./".
583*10465441SEvalZero
584*10465441SEvalZero      Kconfig files are looked up relative to $srctree (unless absolute paths
585*10465441SEvalZero      are used), and .config files are looked up relative to $srctree if they
586*10465441SEvalZero      are not found in the current directory. This is used to support
587*10465441SEvalZero      out-of-tree builds. The C tools use this environment variable in the same
588*10465441SEvalZero      way.
589*10465441SEvalZero
590*10465441SEvalZero      Changing $srctree after creating the Kconfig instance has no effect. Only
591*10465441SEvalZero      the value when the configuration is loaded matters. This avoids surprises
592*10465441SEvalZero      if multiple configurations are loaded with different values for $srctree.
593*10465441SEvalZero
594*10465441SEvalZero    config_prefix:
595*10465441SEvalZero      The value of the $CONFIG_ environment variable when the configuration was
596*10465441SEvalZero      loaded. This is the prefix used (and expected) on symbol names in .config
597*10465441SEvalZero      files and C headers. Defaults to "CONFIG_". Used in the same way in the C
598*10465441SEvalZero      tools.
599*10465441SEvalZero
600*10465441SEvalZero      Like for srctree, only the value of $CONFIG_ when the configuration is
601*10465441SEvalZero      loaded matters.
602*10465441SEvalZero    """
603*10465441SEvalZero    __slots__ = (
604*10465441SEvalZero        "_encoding",
605*10465441SEvalZero        "_functions",
606*10465441SEvalZero        "_set_match",
607*10465441SEvalZero        "_unset_match",
608*10465441SEvalZero        "_warn_for_no_prompt",
609*10465441SEvalZero        "_warn_for_redun_assign",
610*10465441SEvalZero        "_warn_for_undef_assign",
611*10465441SEvalZero        "_warn_to_stderr",
612*10465441SEvalZero        "_warnings_enabled",
613*10465441SEvalZero        "choices",
614*10465441SEvalZero        "comments",
615*10465441SEvalZero        "config_prefix",
616*10465441SEvalZero        "const_syms",
617*10465441SEvalZero        "defconfig_list",
618*10465441SEvalZero        "defined_syms",
619*10465441SEvalZero        "env_vars",
620*10465441SEvalZero        "kconfig_filenames",
621*10465441SEvalZero        "m",
622*10465441SEvalZero        "mainmenu_text",
623*10465441SEvalZero        "menus",
624*10465441SEvalZero        "modules",
625*10465441SEvalZero        "n",
626*10465441SEvalZero        "named_choices",
627*10465441SEvalZero        "srctree",
628*10465441SEvalZero        "syms",
629*10465441SEvalZero        "top_node",
630*10465441SEvalZero        "unique_choices",
631*10465441SEvalZero        "unique_defined_syms",
632*10465441SEvalZero        "variables",
633*10465441SEvalZero        "warnings",
634*10465441SEvalZero        "y",
635*10465441SEvalZero
636*10465441SEvalZero        # Parsing-related
637*10465441SEvalZero        "_parsing_kconfigs",
638*10465441SEvalZero        "_file",
639*10465441SEvalZero        "_filename",
640*10465441SEvalZero        "_linenr",
641*10465441SEvalZero        "_include_path",
642*10465441SEvalZero        "_filestack",
643*10465441SEvalZero        "_line",
644*10465441SEvalZero        "_saved_line",
645*10465441SEvalZero        "_tokens",
646*10465441SEvalZero        "_tokens_i",
647*10465441SEvalZero        "_has_tokens",
648*10465441SEvalZero    )
649*10465441SEvalZero
650*10465441SEvalZero    #
651*10465441SEvalZero    # Public interface
652*10465441SEvalZero    #
653*10465441SEvalZero
654*10465441SEvalZero    def __init__(self, filename="Kconfig", warn=True, warn_to_stderr=True,
655*10465441SEvalZero                 encoding="utf-8"):
656*10465441SEvalZero        """
657*10465441SEvalZero        Creates a new Kconfig object by parsing Kconfig files. Raises
658*10465441SEvalZero        KconfigError on syntax errors. Note that Kconfig files are not the same
659*10465441SEvalZero        as .config files (which store configuration symbol values).
660*10465441SEvalZero
661*10465441SEvalZero        If the environment variable KCONFIG_STRICT is set to "y", warnings will
662*10465441SEvalZero        be generated for all references to undefined symbols within Kconfig
663*10465441SEvalZero        files. The reason this isn't the default is that some projects (e.g.
664*10465441SEvalZero        the Linux kernel) use multiple Kconfig trees (one per architecture)
665*10465441SEvalZero        with many shared Kconfig files, leading to some safe references to
666*10465441SEvalZero        undefined symbols.
667*10465441SEvalZero
668*10465441SEvalZero        KCONFIG_STRICT relies on literal hex values being prefixed with 0x/0X.
669*10465441SEvalZero        They are indistinguishable from references to undefined symbols
670*10465441SEvalZero        otherwise.
671*10465441SEvalZero
672*10465441SEvalZero        KCONFIG_STRICT might enable other warnings that depend on there being
673*10465441SEvalZero        just a single Kconfig tree in the future.
674*10465441SEvalZero
675*10465441SEvalZero        filename (default: "Kconfig"):
676*10465441SEvalZero          The Kconfig file to load. For the Linux kernel, you'll want "Kconfig"
677*10465441SEvalZero          from the top-level directory, as environment variables will make sure
678*10465441SEvalZero          the right Kconfig is included from there (arch/$SRCARCH/Kconfig as of
679*10465441SEvalZero          writing).
680*10465441SEvalZero
681*10465441SEvalZero          If $srctree is set, 'filename' will be looked up relative to it.
682*10465441SEvalZero          $srctree is also used to look up source'd files within Kconfig files.
683*10465441SEvalZero          See the class documentation.
684*10465441SEvalZero
685*10465441SEvalZero          If you are using Kconfiglib via 'make scriptconfig', the filename of
686*10465441SEvalZero          the base base Kconfig file will be in sys.argv[1]. It's currently
687*10465441SEvalZero          always "Kconfig" in practice.
688*10465441SEvalZero
689*10465441SEvalZero        warn (default: True):
690*10465441SEvalZero          True if warnings related to this configuration should be generated.
691*10465441SEvalZero          This can be changed later with Kconfig.enable/disable_warnings(). It
692*10465441SEvalZero          is provided as a constructor argument since warnings might be
693*10465441SEvalZero          generated during parsing.
694*10465441SEvalZero
695*10465441SEvalZero          See the other Kconfig.enable_*_warnings() functions as well, which
696*10465441SEvalZero          enable or suppress certain warnings when warnings are enabled.
697*10465441SEvalZero
698*10465441SEvalZero          All generated warnings are added to the Kconfig.warnings list. See
699*10465441SEvalZero          the class documentation.
700*10465441SEvalZero
701*10465441SEvalZero        warn_to_stderr (default: True):
702*10465441SEvalZero          True if warnings should be printed to stderr in addition to being
703*10465441SEvalZero          added to Kconfig.warnings.
704*10465441SEvalZero
705*10465441SEvalZero          This can be changed later with
706*10465441SEvalZero          Kconfig.enable/disable_stderr_warnings().
707*10465441SEvalZero
708*10465441SEvalZero        encoding (default: "utf-8"):
709*10465441SEvalZero          The encoding to use when reading and writing files. If None, the
710*10465441SEvalZero          encoding specified in the current locale will be used.
711*10465441SEvalZero
712*10465441SEvalZero          The "utf-8" default avoids exceptions on systems that are configured
713*10465441SEvalZero          to use the C locale, which implies an ASCII encoding.
714*10465441SEvalZero
715*10465441SEvalZero          This parameter has no effect on Python 2, due to implementation
716*10465441SEvalZero          issues (regular strings turning into Unicode strings, which are
717*10465441SEvalZero          distinct in Python 2). Python 2 doesn't decode regular strings
718*10465441SEvalZero          anyway.
719*10465441SEvalZero
720*10465441SEvalZero          Related PEP: https://www.python.org/dev/peps/pep-0538/
721*10465441SEvalZero        """
722*10465441SEvalZero        self.srctree = os.environ.get("srctree", "")
723*10465441SEvalZero        self.config_prefix = os.environ.get("CONFIG_", "CONFIG_")
724*10465441SEvalZero
725*10465441SEvalZero        # Regular expressions for parsing .config files
726*10465441SEvalZero        self._set_match = _re_match(self.config_prefix + r"([^=]+)=(.*)")
727*10465441SEvalZero        self._unset_match = \
728*10465441SEvalZero            _re_match(r"# {}([^ ]+) is not set".format(self.config_prefix))
729*10465441SEvalZero
730*10465441SEvalZero
731*10465441SEvalZero        self.warnings = []
732*10465441SEvalZero
733*10465441SEvalZero        self._warnings_enabled = warn
734*10465441SEvalZero        self._warn_to_stderr = warn_to_stderr
735*10465441SEvalZero        self._warn_for_undef_assign = False
736*10465441SEvalZero        self._warn_for_redun_assign = True
737*10465441SEvalZero
738*10465441SEvalZero
739*10465441SEvalZero        self._encoding = encoding
740*10465441SEvalZero
741*10465441SEvalZero
742*10465441SEvalZero        self.syms = {}
743*10465441SEvalZero        self.const_syms = {}
744*10465441SEvalZero        self.defined_syms = []
745*10465441SEvalZero
746*10465441SEvalZero        self.named_choices = {}
747*10465441SEvalZero        self.choices = []
748*10465441SEvalZero
749*10465441SEvalZero        self.menus = []
750*10465441SEvalZero        self.comments = []
751*10465441SEvalZero
752*10465441SEvalZero        for nmy in "n", "m", "y":
753*10465441SEvalZero            sym = Symbol()
754*10465441SEvalZero            sym.kconfig = self
755*10465441SEvalZero            sym.name = nmy
756*10465441SEvalZero            sym.is_constant = True
757*10465441SEvalZero            sym.orig_type = TRISTATE
758*10465441SEvalZero            sym._cached_tri_val = STR_TO_TRI[nmy]
759*10465441SEvalZero
760*10465441SEvalZero            self.const_syms[nmy] = sym
761*10465441SEvalZero
762*10465441SEvalZero        self.n = self.const_syms["n"]
763*10465441SEvalZero        self.m = self.const_syms["m"]
764*10465441SEvalZero        self.y = self.const_syms["y"]
765*10465441SEvalZero
766*10465441SEvalZero        # Make n/m/y well-formed symbols
767*10465441SEvalZero        for nmy in "n", "m", "y":
768*10465441SEvalZero            sym = self.const_syms[nmy]
769*10465441SEvalZero            sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n
770*10465441SEvalZero
771*10465441SEvalZero
772*10465441SEvalZero        # Maps preprocessor variables names to Variable instances
773*10465441SEvalZero        self.variables = {}
774*10465441SEvalZero
775*10465441SEvalZero        # Predefined preprocessor functions, with min/max number of arguments
776*10465441SEvalZero        self._functions = {
777*10465441SEvalZero            "info":       (_info_fn,       1, 1),
778*10465441SEvalZero            "error-if":   (_error_if_fn,   2, 2),
779*10465441SEvalZero            "filename":   (_filename_fn,   0, 0),
780*10465441SEvalZero            "lineno":     (_lineno_fn,     0, 0),
781*10465441SEvalZero            "shell":      (_shell_fn,      1, 1),
782*10465441SEvalZero            "warning-if": (_warning_if_fn, 2, 2),
783*10465441SEvalZero        }
784*10465441SEvalZero
785*10465441SEvalZero
786*10465441SEvalZero        # This is used to determine whether previously unseen symbols should be
787*10465441SEvalZero        # registered. They shouldn't be if we parse expressions after parsing,
788*10465441SEvalZero        # as part of Kconfig.eval_string().
789*10465441SEvalZero        self._parsing_kconfigs = True
790*10465441SEvalZero
791*10465441SEvalZero        self.modules = self._lookup_sym("MODULES")
792*10465441SEvalZero        self.defconfig_list = None
793*10465441SEvalZero
794*10465441SEvalZero        self.top_node = MenuNode()
795*10465441SEvalZero        self.top_node.kconfig = self
796*10465441SEvalZero        self.top_node.item = MENU
797*10465441SEvalZero        self.top_node.is_menuconfig = True
798*10465441SEvalZero        self.top_node.visibility = self.y
799*10465441SEvalZero        self.top_node.prompt = ("Main menu", self.y)
800*10465441SEvalZero        self.top_node.parent = None
801*10465441SEvalZero        self.top_node.dep = self.y
802*10465441SEvalZero        self.top_node.filename = filename
803*10465441SEvalZero        self.top_node.linenr = 1
804*10465441SEvalZero        self.top_node.include_path = ()
805*10465441SEvalZero
806*10465441SEvalZero        # Parse the Kconfig files
807*10465441SEvalZero
808*10465441SEvalZero        # Not used internally. Provided as a convenience.
809*10465441SEvalZero        self.kconfig_filenames = [filename]
810*10465441SEvalZero        self.env_vars = set()
811*10465441SEvalZero
812*10465441SEvalZero        # These implement a single line of "unget" for the parser
813*10465441SEvalZero        self._saved_line = None
814*10465441SEvalZero        self._has_tokens = False
815*10465441SEvalZero
816*10465441SEvalZero        # Keeps track of the location in the parent Kconfig files. Kconfig
817*10465441SEvalZero        # files usually source other Kconfig files. See _enter_file().
818*10465441SEvalZero        self._filestack = []
819*10465441SEvalZero        self._include_path = ()
820*10465441SEvalZero
821*10465441SEvalZero        # The current parsing location
822*10465441SEvalZero        self._filename = filename
823*10465441SEvalZero        self._linenr = 0
824*10465441SEvalZero
825*10465441SEvalZero        # Open the top-level Kconfig file
826*10465441SEvalZero        try:
827*10465441SEvalZero            self._file = self._open(os.path.join(self.srctree, filename), "r")
828*10465441SEvalZero        except IOError as e:
829*10465441SEvalZero            if self.srctree:
830*10465441SEvalZero                print(textwrap.fill(
831*10465441SEvalZero                    _INIT_SRCTREE_NOTE.format(self.srctree), 80))
832*10465441SEvalZero            raise
833*10465441SEvalZero
834*10465441SEvalZero        try:
835*10465441SEvalZero            # Parse everything
836*10465441SEvalZero            self._parse_block(None, self.top_node, self.top_node)
837*10465441SEvalZero        except UnicodeDecodeError as e:
838*10465441SEvalZero            _decoding_error(e, self._filename)
839*10465441SEvalZero
840*10465441SEvalZero        # Close the top-level Kconfig file
841*10465441SEvalZero        self._file.close()
842*10465441SEvalZero
843*10465441SEvalZero        self.top_node.list = self.top_node.next
844*10465441SEvalZero        self.top_node.next = None
845*10465441SEvalZero
846*10465441SEvalZero        self._parsing_kconfigs = False
847*10465441SEvalZero
848*10465441SEvalZero        self.unique_defined_syms = _ordered_unique(self.defined_syms)
849*10465441SEvalZero        self.unique_choices = _ordered_unique(self.choices)
850*10465441SEvalZero
851*10465441SEvalZero        # Do various post-processing of the menu tree
852*10465441SEvalZero        self._finalize_tree(self.top_node, self.y)
853*10465441SEvalZero
854*10465441SEvalZero
855*10465441SEvalZero        # Do sanity checks. Some of these depend on everything being
856*10465441SEvalZero        # finalized.
857*10465441SEvalZero
858*10465441SEvalZero        for sym in self.unique_defined_syms:
859*10465441SEvalZero            _check_sym_sanity(sym)
860*10465441SEvalZero
861*10465441SEvalZero        for choice in self.unique_choices:
862*10465441SEvalZero            _check_choice_sanity(choice)
863*10465441SEvalZero
864*10465441SEvalZero        if os.environ.get("KCONFIG_STRICT") == "y":
865*10465441SEvalZero            self._check_undef_syms()
866*10465441SEvalZero
867*10465441SEvalZero
868*10465441SEvalZero        # Build Symbol._dependents for all symbols and choices
869*10465441SEvalZero        self._build_dep()
870*10465441SEvalZero
871*10465441SEvalZero        # Check for dependency loops
872*10465441SEvalZero        for sym in self.unique_defined_syms:
873*10465441SEvalZero            _check_dep_loop_sym(sym, False)
874*10465441SEvalZero
875*10465441SEvalZero        # Add extra dependencies from choices to choice symbols that get
876*10465441SEvalZero        # awkward during dependency loop detection
877*10465441SEvalZero        self._add_choice_deps()
878*10465441SEvalZero
879*10465441SEvalZero
880*10465441SEvalZero        self._warn_for_no_prompt = True
881*10465441SEvalZero
882*10465441SEvalZero        self.mainmenu_text = self.top_node.prompt[0]
883*10465441SEvalZero
884*10465441SEvalZero    @property
885*10465441SEvalZero    def defconfig_filename(self):
886*10465441SEvalZero        """
887*10465441SEvalZero        See the class documentation.
888*10465441SEvalZero        """
889*10465441SEvalZero        if self.defconfig_list:
890*10465441SEvalZero            for filename, cond in self.defconfig_list.defaults:
891*10465441SEvalZero                if expr_value(cond):
892*10465441SEvalZero                    try:
893*10465441SEvalZero                        with self._open_config(filename.str_value) as f:
894*10465441SEvalZero                            return f.name
895*10465441SEvalZero                    except IOError:
896*10465441SEvalZero                        continue
897*10465441SEvalZero
898*10465441SEvalZero        return None
899*10465441SEvalZero
900*10465441SEvalZero    def load_config(self, filename, replace=True):
901*10465441SEvalZero        """
902*10465441SEvalZero        Loads symbol values from a file in the .config format. Equivalent to
903*10465441SEvalZero        calling Symbol.set_value() to set each of the values.
904*10465441SEvalZero
905*10465441SEvalZero        "# CONFIG_FOO is not set" within a .config file sets the user value of
906*10465441SEvalZero        FOO to n. The C tools work the same way.
907*10465441SEvalZero
908*10465441SEvalZero        The Symbol.user_value attribute can be inspected afterwards to see what
909*10465441SEvalZero        value the symbol was assigned in the .config file (if any). The user
910*10465441SEvalZero        value might differ from Symbol.str/tri_value if there are unsatisfied
911*10465441SEvalZero        dependencies.
912*10465441SEvalZero
913*10465441SEvalZero        filename:
914*10465441SEvalZero          The file to load. Respects $srctree if set (see the class
915*10465441SEvalZero          documentation).
916*10465441SEvalZero
917*10465441SEvalZero        replace (default: True):
918*10465441SEvalZero          True if all existing user values should be cleared before loading the
919*10465441SEvalZero          .config.
920*10465441SEvalZero        """
921*10465441SEvalZero        # Disable the warning about assigning to symbols without prompts. This
922*10465441SEvalZero        # is normal and expected within a .config file.
923*10465441SEvalZero        self._warn_for_no_prompt = False
924*10465441SEvalZero
925*10465441SEvalZero        # This stub only exists to make sure _warn_for_no_prompt gets reenabled
926*10465441SEvalZero        try:
927*10465441SEvalZero            self._load_config(filename, replace)
928*10465441SEvalZero        except UnicodeDecodeError as e:
929*10465441SEvalZero            _decoding_error(e, filename)
930*10465441SEvalZero        finally:
931*10465441SEvalZero            self._warn_for_no_prompt = True
932*10465441SEvalZero
933*10465441SEvalZero    def _load_config(self, filename, replace):
934*10465441SEvalZero        with self._open_config(filename) as f:
935*10465441SEvalZero            if replace:
936*10465441SEvalZero                # If we're replacing the configuration, keep track of which
937*10465441SEvalZero                # symbols and choices got set so that we can unset the rest
938*10465441SEvalZero                # later. This avoids invalidating everything and is faster.
939*10465441SEvalZero                # Another benefit is that invalidation must be rock solid for
940*10465441SEvalZero                # it to work, making it a good test.
941*10465441SEvalZero
942*10465441SEvalZero                for sym in self.unique_defined_syms:
943*10465441SEvalZero                    sym._was_set = False
944*10465441SEvalZero
945*10465441SEvalZero                for choice in self.unique_choices:
946*10465441SEvalZero                    choice._was_set = False
947*10465441SEvalZero
948*10465441SEvalZero            # Small optimizations
949*10465441SEvalZero            set_match = self._set_match
950*10465441SEvalZero            unset_match = self._unset_match
951*10465441SEvalZero            syms = self.syms
952*10465441SEvalZero
953*10465441SEvalZero            for linenr, line in enumerate(f, 1):
954*10465441SEvalZero                # The C tools ignore trailing whitespace
955*10465441SEvalZero                line = line.rstrip()
956*10465441SEvalZero
957*10465441SEvalZero                match = set_match(line)
958*10465441SEvalZero                if match:
959*10465441SEvalZero                    name, val = match.groups()
960*10465441SEvalZero                    if name not in syms:
961*10465441SEvalZero                        self._warn_undef_assign_load(name, val, filename,
962*10465441SEvalZero                                                     linenr)
963*10465441SEvalZero                        continue
964*10465441SEvalZero
965*10465441SEvalZero                    sym = syms[name]
966*10465441SEvalZero                    if not sym.nodes:
967*10465441SEvalZero                        self._warn_undef_assign_load(name, val, filename,
968*10465441SEvalZero                                                     linenr)
969*10465441SEvalZero                        continue
970*10465441SEvalZero
971*10465441SEvalZero                    if sym.orig_type in (BOOL, TRISTATE):
972*10465441SEvalZero                        # The C implementation only checks the first character
973*10465441SEvalZero                        # to the right of '=', for whatever reason
974*10465441SEvalZero                        if not ((sym.orig_type is BOOL and
975*10465441SEvalZero                                 val.startswith(("n", "y"))) or \
976*10465441SEvalZero                                (sym.orig_type is TRISTATE and
977*10465441SEvalZero                                 val.startswith(("n", "m", "y")))):
978*10465441SEvalZero                            self._warn("'{}' is not a valid value for the {} "
979*10465441SEvalZero                                       "symbol {}. Assignment ignored."
980*10465441SEvalZero                                       .format(val, TYPE_TO_STR[sym.orig_type],
981*10465441SEvalZero                                               _name_and_loc(sym)),
982*10465441SEvalZero                                       filename, linenr)
983*10465441SEvalZero                            continue
984*10465441SEvalZero
985*10465441SEvalZero                        val = val[0]
986*10465441SEvalZero
987*10465441SEvalZero                        if sym.choice and val != "n":
988*10465441SEvalZero                            # During .config loading, we infer the mode of the
989*10465441SEvalZero                            # choice from the kind of values that are assigned
990*10465441SEvalZero                            # to the choice symbols
991*10465441SEvalZero
992*10465441SEvalZero                            prev_mode = sym.choice.user_value
993*10465441SEvalZero                            if prev_mode is not None and \
994*10465441SEvalZero                               TRI_TO_STR[prev_mode] != val:
995*10465441SEvalZero
996*10465441SEvalZero                                self._warn("both m and y assigned to symbols "
997*10465441SEvalZero                                           "within the same choice",
998*10465441SEvalZero                                           filename, linenr)
999*10465441SEvalZero
1000*10465441SEvalZero                            # Set the choice's mode
1001*10465441SEvalZero                            sym.choice.set_value(val)
1002*10465441SEvalZero
1003*10465441SEvalZero                    elif sym.orig_type is STRING:
1004*10465441SEvalZero                        match = _conf_string_match(val)
1005*10465441SEvalZero                        if not match:
1006*10465441SEvalZero                            self._warn("malformed string literal in "
1007*10465441SEvalZero                                       "assignment to {}. Assignment ignored."
1008*10465441SEvalZero                                       .format(_name_and_loc(sym)),
1009*10465441SEvalZero                                       filename, linenr)
1010*10465441SEvalZero                            continue
1011*10465441SEvalZero
1012*10465441SEvalZero                        val = unescape(match.group(1))
1013*10465441SEvalZero
1014*10465441SEvalZero                else:
1015*10465441SEvalZero                    match = unset_match(line)
1016*10465441SEvalZero                    if not match:
1017*10465441SEvalZero                        # Print a warning for lines that match neither
1018*10465441SEvalZero                        # set_match() nor unset_match() and that are not blank
1019*10465441SEvalZero                        # lines or comments. 'line' has already been
1020*10465441SEvalZero                        # rstrip()'d, so blank lines show up as "" here.
1021*10465441SEvalZero                        if line and not line.lstrip().startswith("#"):
1022*10465441SEvalZero                            self._warn("ignoring malformed line '{}'"
1023*10465441SEvalZero                                       .format(line),
1024*10465441SEvalZero                                       filename, linenr)
1025*10465441SEvalZero
1026*10465441SEvalZero                        continue
1027*10465441SEvalZero
1028*10465441SEvalZero                    name = match.group(1)
1029*10465441SEvalZero                    if name not in syms:
1030*10465441SEvalZero                        self._warn_undef_assign_load(name, "n", filename,
1031*10465441SEvalZero                                                     linenr)
1032*10465441SEvalZero                        continue
1033*10465441SEvalZero
1034*10465441SEvalZero                    sym = syms[name]
1035*10465441SEvalZero                    if sym.orig_type not in (BOOL, TRISTATE):
1036*10465441SEvalZero                        continue
1037*10465441SEvalZero
1038*10465441SEvalZero                    val = "n"
1039*10465441SEvalZero
1040*10465441SEvalZero                # Done parsing the assignment. Set the value.
1041*10465441SEvalZero
1042*10465441SEvalZero                if sym._was_set:
1043*10465441SEvalZero                    # Use strings for bool/tristate user values in the warning
1044*10465441SEvalZero                    if sym.orig_type in (BOOL, TRISTATE):
1045*10465441SEvalZero                        display_user_val = TRI_TO_STR[sym.user_value]
1046*10465441SEvalZero                    else:
1047*10465441SEvalZero                        display_user_val = sym.user_value
1048*10465441SEvalZero
1049*10465441SEvalZero                    warn_msg = '{} set more than once. Old value: "{}", new value: "{}".'.format(
1050*10465441SEvalZero                        _name_and_loc(sym), display_user_val, val
1051*10465441SEvalZero                    )
1052*10465441SEvalZero
1053*10465441SEvalZero                    if display_user_val == val:
1054*10465441SEvalZero                        self._warn_redun_assign(warn_msg, filename, linenr)
1055*10465441SEvalZero                    else:
1056*10465441SEvalZero                        self._warn(             warn_msg, filename, linenr)
1057*10465441SEvalZero
1058*10465441SEvalZero                sym.set_value(val)
1059*10465441SEvalZero
1060*10465441SEvalZero        if replace:
1061*10465441SEvalZero            # If we're replacing the configuration, unset the symbols that
1062*10465441SEvalZero            # didn't get set
1063*10465441SEvalZero
1064*10465441SEvalZero            for sym in self.unique_defined_syms:
1065*10465441SEvalZero                if not sym._was_set:
1066*10465441SEvalZero                    sym.unset_value()
1067*10465441SEvalZero
1068*10465441SEvalZero            for choice in self.unique_choices:
1069*10465441SEvalZero                if not choice._was_set:
1070*10465441SEvalZero                    choice.unset_value()
1071*10465441SEvalZero
1072*10465441SEvalZero    def write_autoconf(self, filename,
1073*10465441SEvalZero                       header="/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
1074*10465441SEvalZero        r"""
1075*10465441SEvalZero        Writes out symbol values as a C header file, matching the format used
1076*10465441SEvalZero        by include/generated/autoconf.h in the kernel.
1077*10465441SEvalZero
1078*10465441SEvalZero        The ordering of the #defines matches the one generated by
1079*10465441SEvalZero        write_config(). The order in the C implementation depends on the hash
1080*10465441SEvalZero        table implementation as of writing, and so won't match.
1081*10465441SEvalZero
1082*10465441SEvalZero        filename:
1083*10465441SEvalZero          Self-explanatory.
1084*10465441SEvalZero
1085*10465441SEvalZero        header (default: "/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
1086*10465441SEvalZero          Text that will be inserted verbatim at the beginning of the file. You
1087*10465441SEvalZero          would usually want it enclosed in '/* */' to make it a C comment,
1088*10465441SEvalZero          and include a final terminating newline.
1089*10465441SEvalZero        """
1090*10465441SEvalZero        with self._open(filename, "w") as f:
1091*10465441SEvalZero            f.write(header)
1092*10465441SEvalZero
1093*10465441SEvalZero            for sym in self.unique_defined_syms:
1094*10465441SEvalZero                # Note: _write_to_conf is determined when the value is
1095*10465441SEvalZero                # calculated. This is a hidden function call due to
1096*10465441SEvalZero                # property magic.
1097*10465441SEvalZero                val = sym.str_value
1098*10465441SEvalZero                if sym._write_to_conf:
1099*10465441SEvalZero                    if sym.orig_type in (BOOL, TRISTATE):
1100*10465441SEvalZero                        if val != "n":
1101*10465441SEvalZero                            f.write("#define {}{}{} 1\n"
1102*10465441SEvalZero                                    .format(self.config_prefix, sym.name,
1103*10465441SEvalZero                                            "_MODULE" if val == "m" else ""))
1104*10465441SEvalZero
1105*10465441SEvalZero                    elif sym.orig_type is STRING:
1106*10465441SEvalZero                        f.write('#define {}{} "{}"\n'
1107*10465441SEvalZero                                .format(self.config_prefix, sym.name,
1108*10465441SEvalZero                                        escape(val)))
1109*10465441SEvalZero
1110*10465441SEvalZero                    elif sym.orig_type in (INT, HEX):
1111*10465441SEvalZero                        if sym.orig_type is HEX and \
1112*10465441SEvalZero                           not val.startswith(("0x", "0X")):
1113*10465441SEvalZero                            val = "0x" + val
1114*10465441SEvalZero
1115*10465441SEvalZero                        f.write("#define {}{} {}\n"
1116*10465441SEvalZero                                .format(self.config_prefix, sym.name, val))
1117*10465441SEvalZero
1118*10465441SEvalZero                    else:
1119*10465441SEvalZero                        _internal_error("Internal error while creating C "
1120*10465441SEvalZero                                        'header: unknown type "{}".'
1121*10465441SEvalZero                                        .format(sym.orig_type))
1122*10465441SEvalZero
1123*10465441SEvalZero    def write_config(self, filename,
1124*10465441SEvalZero                     header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
1125*10465441SEvalZero        r"""
1126*10465441SEvalZero        Writes out symbol values in the .config format. The format matches the
1127*10465441SEvalZero        C implementation, including ordering.
1128*10465441SEvalZero
1129*10465441SEvalZero        Symbols appear in the same order in generated .config files as they do
1130*10465441SEvalZero        in the Kconfig files. For symbols defined in multiple locations, a
1131*10465441SEvalZero        single assignment is written out corresponding to the first location
1132*10465441SEvalZero        where the symbol is defined.
1133*10465441SEvalZero
1134*10465441SEvalZero        See the 'Intro to symbol values' section in the module docstring to
1135*10465441SEvalZero        understand which symbols get written out.
1136*10465441SEvalZero
1137*10465441SEvalZero        filename:
1138*10465441SEvalZero          Self-explanatory.
1139*10465441SEvalZero
1140*10465441SEvalZero        header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
1141*10465441SEvalZero          Text that will be inserted verbatim at the beginning of the file. You
1142*10465441SEvalZero          would usually want each line to start with '#' to make it a comment,
1143*10465441SEvalZero          and include a final terminating newline.
1144*10465441SEvalZero        """
1145*10465441SEvalZero        with self._open(filename, "w") as f:
1146*10465441SEvalZero            f.write(header)
1147*10465441SEvalZero
1148*10465441SEvalZero            # written mainmenu_text
1149*10465441SEvalZero            # The prompt (title) of the top_node menu, with Kconfig variable references
1150*10465441SEvalZero            # ("$FOO") expanded. Defaults to "Linux Kernel Configuration" (like in the
1151*10465441SEvalZero            # C tools). Can be changed with the 'mainmenu' statement (see
1152*10465441SEvalZero            # kconfig-language.txt).
1153*10465441SEvalZero            f.write("# {}\n#\n".format(self.top_node.prompt[0]))
1154*10465441SEvalZero
1155*10465441SEvalZero            for node in self.node_iter(unique_syms=True):
1156*10465441SEvalZero                item = node.item
1157*10465441SEvalZero
1158*10465441SEvalZero                if isinstance(item, Symbol):
1159*10465441SEvalZero                    f.write(item.config_string)
1160*10465441SEvalZero
1161*10465441SEvalZero                elif expr_value(node.dep) and \
1162*10465441SEvalZero                     ((item is MENU and expr_value(node.visibility)) or
1163*10465441SEvalZero                       item is COMMENT):
1164*10465441SEvalZero
1165*10465441SEvalZero                    f.write("\n#\n# {}\n#\n".format(node.prompt[0]))
1166*10465441SEvalZero
1167*10465441SEvalZero    def write_min_config(self, filename,
1168*10465441SEvalZero                         header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
1169*10465441SEvalZero        """
1170*10465441SEvalZero        Writes out a "minimal" configuration file, omitting symbols whose value
1171*10465441SEvalZero        matches their default value. The format matches the one produced by
1172*10465441SEvalZero        'make savedefconfig'.
1173*10465441SEvalZero
1174*10465441SEvalZero        The resulting configuration file is incomplete, but a complete
1175*10465441SEvalZero        configuration can be derived from it by loading it. Minimal
1176*10465441SEvalZero        configuration files can serve as a more manageable configuration format
1177*10465441SEvalZero        compared to a "full" .config file, especially when configurations files
1178*10465441SEvalZero        are merged or edited by hand.
1179*10465441SEvalZero
1180*10465441SEvalZero        filename:
1181*10465441SEvalZero          Self-explanatory.
1182*10465441SEvalZero
1183*10465441SEvalZero        header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
1184*10465441SEvalZero          Text that will be inserted verbatim at the beginning of the file. You
1185*10465441SEvalZero          would usually want each line to start with '#' to make it a comment,
1186*10465441SEvalZero          and include a final terminating newline.
1187*10465441SEvalZero        """
1188*10465441SEvalZero        with self._open(filename, "w") as f:
1189*10465441SEvalZero            f.write(header)
1190*10465441SEvalZero
1191*10465441SEvalZero            for sym in self.unique_defined_syms:
1192*10465441SEvalZero                # Skip symbols that cannot be changed. Only check
1193*10465441SEvalZero                # non-choice symbols, as selects don't affect choice
1194*10465441SEvalZero                # symbols.
1195*10465441SEvalZero                if not sym.choice and \
1196*10465441SEvalZero                   sym.visibility <= expr_value(sym.rev_dep):
1197*10465441SEvalZero                    continue
1198*10465441SEvalZero
1199*10465441SEvalZero                # Skip symbols whose value matches their default
1200*10465441SEvalZero                if sym.str_value == sym._str_default():
1201*10465441SEvalZero                    continue
1202*10465441SEvalZero
1203*10465441SEvalZero                # Skip symbols that would be selected by default in a
1204*10465441SEvalZero                # choice, unless the choice is optional or the symbol type
1205*10465441SEvalZero                # isn't bool (it might be possible to set the choice mode
1206*10465441SEvalZero                # to n or the symbol to m in those cases).
1207*10465441SEvalZero                if sym.choice and \
1208*10465441SEvalZero                   not sym.choice.is_optional and \
1209*10465441SEvalZero                   sym.choice._get_selection_from_defaults() is sym and \
1210*10465441SEvalZero                   sym.orig_type is BOOL and \
1211*10465441SEvalZero                   sym.tri_value == 2:
1212*10465441SEvalZero                    continue
1213*10465441SEvalZero
1214*10465441SEvalZero                f.write(sym.config_string)
1215*10465441SEvalZero
1216*10465441SEvalZero    def sync_deps(self, path):
1217*10465441SEvalZero        """
1218*10465441SEvalZero        Creates or updates a directory structure that can be used to avoid
1219*10465441SEvalZero        doing a full rebuild whenever the configuration is changed, mirroring
1220*10465441SEvalZero        include/config/ in the kernel.
1221*10465441SEvalZero
1222*10465441SEvalZero        This function is intended to be called during each build, before
1223*10465441SEvalZero        compiling source files that depend on configuration symbols.
1224*10465441SEvalZero
1225*10465441SEvalZero        path:
1226*10465441SEvalZero          Path to directory
1227*10465441SEvalZero
1228*10465441SEvalZero        sync_deps(path) does the following:
1229*10465441SEvalZero
1230*10465441SEvalZero          1. If the directory <path> does not exist, it is created.
1231*10465441SEvalZero
1232*10465441SEvalZero          2. If <path>/auto.conf exists, old symbol values are loaded from it,
1233*10465441SEvalZero             which are then compared against the current symbol values. If a
1234*10465441SEvalZero             symbol has changed value (would generate different output in
1235*10465441SEvalZero             autoconf.h compared to before), the change is signaled by
1236*10465441SEvalZero             touch'ing a file corresponding to the symbol.
1237*10465441SEvalZero
1238*10465441SEvalZero             The first time sync_deps() is run on a directory, <path>/auto.conf
1239*10465441SEvalZero             won't exist, and no old symbol values will be available. This
1240*10465441SEvalZero             logically has the same effect as updating the entire
1241*10465441SEvalZero             configuration.
1242*10465441SEvalZero
1243*10465441SEvalZero             The path to a symbol's file is calculated from the symbol's name
1244*10465441SEvalZero             by replacing all '_' with '/' and appending '.h'. For example, the
1245*10465441SEvalZero             symbol FOO_BAR_BAZ gets the file <path>/foo/bar/baz.h, and FOO
1246*10465441SEvalZero             gets the file <path>/foo.h.
1247*10465441SEvalZero
1248*10465441SEvalZero             This scheme matches the C tools. The point is to avoid having a
1249*10465441SEvalZero             single directory with a huge number of files, which the underlying
1250*10465441SEvalZero             filesystem might not handle well.
1251*10465441SEvalZero
1252*10465441SEvalZero          3. A new auto.conf with the current symbol values is written, to keep
1253*10465441SEvalZero             track of them for the next build.
1254*10465441SEvalZero
1255*10465441SEvalZero
1256*10465441SEvalZero        The last piece of the puzzle is knowing what symbols each source file
1257*10465441SEvalZero        depends on. Knowing that, dependencies can be added from source files
1258*10465441SEvalZero        to the files corresponding to the symbols they depends on. The source
1259*10465441SEvalZero        file will then get recompiled (only) when the symbol value changes
1260*10465441SEvalZero        (provided sync_deps() is run first during each build).
1261*10465441SEvalZero
1262*10465441SEvalZero        The tool in the kernel that extracts symbol dependencies from source
1263*10465441SEvalZero        files is scripts/basic/fixdep.c. Missing symbol files also correspond
1264*10465441SEvalZero        to "not changed", which fixdep deals with by using the $(wildcard) Make
1265*10465441SEvalZero        function when adding symbol prerequisites to source files.
1266*10465441SEvalZero
1267*10465441SEvalZero        In case you need a different scheme for your project, the sync_deps()
1268*10465441SEvalZero        implementation can be used as a template."""
1269*10465441SEvalZero        if not os.path.exists(path):
1270*10465441SEvalZero            os.mkdir(path, 0o755)
1271*10465441SEvalZero
1272*10465441SEvalZero        # This setup makes sure that at least the current working directory
1273*10465441SEvalZero        # gets reset if things fail
1274*10465441SEvalZero        prev_dir = os.getcwd()
1275*10465441SEvalZero        try:
1276*10465441SEvalZero            # cd'ing into the symbol file directory simplifies
1277*10465441SEvalZero            # _sync_deps() and saves some work
1278*10465441SEvalZero            os.chdir(path)
1279*10465441SEvalZero            self._sync_deps()
1280*10465441SEvalZero        finally:
1281*10465441SEvalZero            os.chdir(prev_dir)
1282*10465441SEvalZero
1283*10465441SEvalZero    def _sync_deps(self):
1284*10465441SEvalZero        # Load old values from auto.conf, if any
1285*10465441SEvalZero        self._load_old_vals()
1286*10465441SEvalZero
1287*10465441SEvalZero        for sym in self.unique_defined_syms:
1288*10465441SEvalZero            # Note: _write_to_conf is determined when the value is
1289*10465441SEvalZero            # calculated. This is a hidden function call due to
1290*10465441SEvalZero            # property magic.
1291*10465441SEvalZero            val = sym.str_value
1292*10465441SEvalZero
1293*10465441SEvalZero            # Note: n tristate values do not get written to auto.conf and
1294*10465441SEvalZero            # autoconf.h, making a missing symbol logically equivalent to n
1295*10465441SEvalZero
1296*10465441SEvalZero            if sym._write_to_conf:
1297*10465441SEvalZero                if sym._old_val is None and \
1298*10465441SEvalZero                   sym.orig_type in (BOOL, TRISTATE) and \
1299*10465441SEvalZero                   val == "n":
1300*10465441SEvalZero                    # No old value (the symbol was missing or n), new value n.
1301*10465441SEvalZero                    # No change.
1302*10465441SEvalZero                    continue
1303*10465441SEvalZero
1304*10465441SEvalZero                if val == sym._old_val:
1305*10465441SEvalZero                    # New value matches old. No change.
1306*10465441SEvalZero                    continue
1307*10465441SEvalZero
1308*10465441SEvalZero            elif sym._old_val is None:
1309*10465441SEvalZero                # The symbol wouldn't appear in autoconf.h (because
1310*10465441SEvalZero                # _write_to_conf is false), and it wouldn't have appeared in
1311*10465441SEvalZero                # autoconf.h previously either (because it didn't appear in
1312*10465441SEvalZero                # auto.conf). No change.
1313*10465441SEvalZero                continue
1314*10465441SEvalZero
1315*10465441SEvalZero            # 'sym' has a new value. Flag it.
1316*10465441SEvalZero
1317*10465441SEvalZero            sym_path = sym.name.lower().replace("_", os.sep) + ".h"
1318*10465441SEvalZero            sym_path_dir = os.path.dirname(sym_path)
1319*10465441SEvalZero            if sym_path_dir and not os.path.exists(sym_path_dir):
1320*10465441SEvalZero                os.makedirs(sym_path_dir, 0o755)
1321*10465441SEvalZero
1322*10465441SEvalZero            # A kind of truncating touch, mirroring the C tools
1323*10465441SEvalZero            os.close(os.open(
1324*10465441SEvalZero                sym_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644))
1325*10465441SEvalZero
1326*10465441SEvalZero        # Remember the current values as the "new old" values.
1327*10465441SEvalZero        #
1328*10465441SEvalZero        # This call could go anywhere after the call to _load_old_vals(), but
1329*10465441SEvalZero        # putting it last means _sync_deps() can be safely rerun if it fails
1330*10465441SEvalZero        # before this point.
1331*10465441SEvalZero        self._write_old_vals()
1332*10465441SEvalZero
1333*10465441SEvalZero    def _write_old_vals(self):
1334*10465441SEvalZero        # Helper for writing auto.conf. Basically just a simplified
1335*10465441SEvalZero        # write_config() that doesn't write any comments (including
1336*10465441SEvalZero        # '# CONFIG_FOO is not set' comments). The format matches the C
1337*10465441SEvalZero        # implementation, though the ordering is arbitrary there (depends on
1338*10465441SEvalZero        # the hash table implementation).
1339*10465441SEvalZero        #
1340*10465441SEvalZero        # A separate helper function is neater than complicating write_config()
1341*10465441SEvalZero        # by passing a flag to it, plus we only need to look at symbols here.
1342*10465441SEvalZero
1343*10465441SEvalZero        with self._open("auto.conf", "w") as f:
1344*10465441SEvalZero            for sym in self.unique_defined_syms:
1345*10465441SEvalZero                if not (sym.orig_type in (BOOL, TRISTATE) and
1346*10465441SEvalZero                        not sym.tri_value):
1347*10465441SEvalZero                    f.write(sym.config_string)
1348*10465441SEvalZero
1349*10465441SEvalZero    def _load_old_vals(self):
1350*10465441SEvalZero        # Loads old symbol values from auto.conf into a dedicated
1351*10465441SEvalZero        # Symbol._old_val field. Mirrors load_config().
1352*10465441SEvalZero        #
1353*10465441SEvalZero        # The extra field could be avoided with some trickery involving dumping
1354*10465441SEvalZero        # symbol values and restoring them later, but this is simpler and
1355*10465441SEvalZero        # faster. The C tools also use a dedicated field for this purpose.
1356*10465441SEvalZero
1357*10465441SEvalZero        for sym in self.unique_defined_syms:
1358*10465441SEvalZero            sym._old_val = None
1359*10465441SEvalZero
1360*10465441SEvalZero        if not os.path.exists("auto.conf"):
1361*10465441SEvalZero            # No old values
1362*10465441SEvalZero            return
1363*10465441SEvalZero
1364*10465441SEvalZero        with self._open("auto.conf", "r") as f:
1365*10465441SEvalZero            for line in f:
1366*10465441SEvalZero                match = self._set_match(line)
1367*10465441SEvalZero                if not match:
1368*10465441SEvalZero                    # We only expect CONFIG_FOO=... (and possibly a header
1369*10465441SEvalZero                    # comment) in auto.conf
1370*10465441SEvalZero                    continue
1371*10465441SEvalZero
1372*10465441SEvalZero                name, val = match.groups()
1373*10465441SEvalZero                if name in self.syms:
1374*10465441SEvalZero                    sym = self.syms[name]
1375*10465441SEvalZero
1376*10465441SEvalZero                    if sym.orig_type is STRING:
1377*10465441SEvalZero                        match = _conf_string_match(val)
1378*10465441SEvalZero                        if not match:
1379*10465441SEvalZero                            continue
1380*10465441SEvalZero                        val = unescape(match.group(1))
1381*10465441SEvalZero
1382*10465441SEvalZero                    self.syms[name]._old_val = val
1383*10465441SEvalZero
1384*10465441SEvalZero    def node_iter(self, unique_syms=False):
1385*10465441SEvalZero        """
1386*10465441SEvalZero        Returns a generator for iterating through all MenuNode's in the Kconfig
1387*10465441SEvalZero        tree. The iteration is done in Kconfig definition order (the children
1388*10465441SEvalZero        of a node are visited before the next node is visited).
1389*10465441SEvalZero
1390*10465441SEvalZero        The Kconfig.top_node menu node is skipped. It contains an implicit menu
1391*10465441SEvalZero        that holds the top-level items.
1392*10465441SEvalZero
1393*10465441SEvalZero        As an example, the following code will produce a list equal to
1394*10465441SEvalZero        Kconfig.defined_syms:
1395*10465441SEvalZero
1396*10465441SEvalZero          defined_syms = [node.item for node in kconf.node_iter()
1397*10465441SEvalZero                          if isinstance(node.item, Symbol)]
1398*10465441SEvalZero
1399*10465441SEvalZero        unique_syms (default: False):
1400*10465441SEvalZero          If True, only the first MenuNode will be included for symbols defined
1401*10465441SEvalZero          in multiple locations.
1402*10465441SEvalZero
1403*10465441SEvalZero          Using kconf.node_iter(True) in the example above would give a list
1404*10465441SEvalZero          equal to unique_defined_syms.
1405*10465441SEvalZero        """
1406*10465441SEvalZero        if unique_syms:
1407*10465441SEvalZero            for sym in self.unique_defined_syms:
1408*10465441SEvalZero                sym._visited = False
1409*10465441SEvalZero
1410*10465441SEvalZero        node = self.top_node
1411*10465441SEvalZero        while 1:
1412*10465441SEvalZero            # Jump to the next node with an iterative tree walk
1413*10465441SEvalZero            if node.list:
1414*10465441SEvalZero                node = node.list
1415*10465441SEvalZero            elif node.next:
1416*10465441SEvalZero                node = node.next
1417*10465441SEvalZero            else:
1418*10465441SEvalZero                while node.parent:
1419*10465441SEvalZero                    node = node.parent
1420*10465441SEvalZero                    if node.next:
1421*10465441SEvalZero                        node = node.next
1422*10465441SEvalZero                        break
1423*10465441SEvalZero                else:
1424*10465441SEvalZero                    # No more nodes
1425*10465441SEvalZero                    return
1426*10465441SEvalZero
1427*10465441SEvalZero            if unique_syms and isinstance(node.item, Symbol):
1428*10465441SEvalZero                if node.item._visited:
1429*10465441SEvalZero                    continue
1430*10465441SEvalZero                node.item._visited = True
1431*10465441SEvalZero
1432*10465441SEvalZero            yield node
1433*10465441SEvalZero
1434*10465441SEvalZero    def eval_string(self, s):
1435*10465441SEvalZero        """
1436*10465441SEvalZero        Returns the tristate value of the expression 's', represented as 0, 1,
1437*10465441SEvalZero        and 2 for n, m, and y, respectively. Raises KconfigError if syntax
1438*10465441SEvalZero        errors are detected in 's'. Warns if undefined symbols are referenced.
1439*10465441SEvalZero
1440*10465441SEvalZero        As an example, if FOO and BAR are tristate symbols at least one of
1441*10465441SEvalZero        which has the value y, then config.eval_string("y && (FOO || BAR)")
1442*10465441SEvalZero        returns 2 (y).
1443*10465441SEvalZero
1444*10465441SEvalZero        To get the string value of non-bool/tristate symbols, use
1445*10465441SEvalZero        Symbol.str_value. eval_string() always returns a tristate value, and
1446*10465441SEvalZero        all non-bool/tristate symbols have the tristate value 0 (n).
1447*10465441SEvalZero
1448*10465441SEvalZero        The expression parsing is consistent with how parsing works for
1449*10465441SEvalZero        conditional ('if ...') expressions in the configuration, and matches
1450*10465441SEvalZero        the C implementation. m is rewritten to 'm && MODULES', so
1451*10465441SEvalZero        eval_string("m") will return 0 (n) unless modules are enabled.
1452*10465441SEvalZero        """
1453*10465441SEvalZero        # The parser is optimized to be fast when parsing Kconfig files (where
1454*10465441SEvalZero        # an expression can never appear at the beginning of a line). We have
1455*10465441SEvalZero        # to monkey-patch things a bit here to reuse it.
1456*10465441SEvalZero
1457*10465441SEvalZero        self._filename = None
1458*10465441SEvalZero
1459*10465441SEvalZero        # Don't include the "if " from below to avoid giving confusing error
1460*10465441SEvalZero        # messages
1461*10465441SEvalZero        self._line = s
1462*10465441SEvalZero        # [1:] removes the _T_IF token
1463*10465441SEvalZero        self._tokens = self._tokenize("if " + s)[1:]
1464*10465441SEvalZero        self._tokens_i = -1
1465*10465441SEvalZero
1466*10465441SEvalZero        return expr_value(self._expect_expr_and_eol())  # transform_m
1467*10465441SEvalZero
1468*10465441SEvalZero    def unset_values(self):
1469*10465441SEvalZero        """
1470*10465441SEvalZero        Resets the user values of all symbols, as if Kconfig.load_config() or
1471*10465441SEvalZero        Symbol.set_value() had never been called.
1472*10465441SEvalZero        """
1473*10465441SEvalZero        self._warn_for_no_prompt = False
1474*10465441SEvalZero        try:
1475*10465441SEvalZero            # set_value() already rejects undefined symbols, and they don't
1476*10465441SEvalZero            # need to be invalidated (because their value never changes), so we
1477*10465441SEvalZero            # can just iterate over defined symbols
1478*10465441SEvalZero            for sym in self.unique_defined_syms:
1479*10465441SEvalZero                sym.unset_value()
1480*10465441SEvalZero
1481*10465441SEvalZero            for choice in self.unique_choices:
1482*10465441SEvalZero                choice.unset_value()
1483*10465441SEvalZero        finally:
1484*10465441SEvalZero            self._warn_for_no_prompt = True
1485*10465441SEvalZero
1486*10465441SEvalZero    def enable_warnings(self):
1487*10465441SEvalZero        """
1488*10465441SEvalZero        See Kconfig.__init__().
1489*10465441SEvalZero        """
1490*10465441SEvalZero        self._warnings_enabled = True
1491*10465441SEvalZero
1492*10465441SEvalZero    def disable_warnings(self):
1493*10465441SEvalZero        """
1494*10465441SEvalZero        See Kconfig.__init__().
1495*10465441SEvalZero        """
1496*10465441SEvalZero        self._warnings_enabled = False
1497*10465441SEvalZero
1498*10465441SEvalZero    def enable_stderr_warnings(self):
1499*10465441SEvalZero        """
1500*10465441SEvalZero        See Kconfig.__init__().
1501*10465441SEvalZero        """
1502*10465441SEvalZero        self._warn_to_stderr = True
1503*10465441SEvalZero
1504*10465441SEvalZero    def disable_stderr_warnings(self):
1505*10465441SEvalZero        """
1506*10465441SEvalZero        See Kconfig.__init__().
1507*10465441SEvalZero        """
1508*10465441SEvalZero        self._warn_to_stderr = False
1509*10465441SEvalZero
1510*10465441SEvalZero    def enable_undef_warnings(self):
1511*10465441SEvalZero        """
1512*10465441SEvalZero        Enables warnings for assignments to undefined symbols. Disabled by
1513*10465441SEvalZero        default since they tend to be spammy for Kernel configurations (and
1514*10465441SEvalZero        mostly suggests cleanups).
1515*10465441SEvalZero        """
1516*10465441SEvalZero        self._warn_for_undef_assign = True
1517*10465441SEvalZero
1518*10465441SEvalZero    def disable_undef_warnings(self):
1519*10465441SEvalZero        """
1520*10465441SEvalZero        See enable_undef_assign().
1521*10465441SEvalZero        """
1522*10465441SEvalZero        self._warn_for_undef_assign = False
1523*10465441SEvalZero
1524*10465441SEvalZero    def enable_redun_warnings(self):
1525*10465441SEvalZero        """
1526*10465441SEvalZero        Enables warnings for duplicated assignments in .config files that all
1527*10465441SEvalZero        set the same value.
1528*10465441SEvalZero
1529*10465441SEvalZero        These warnings are enabled by default. Disabling them might be helpful
1530*10465441SEvalZero        in certain cases when merging configurations.
1531*10465441SEvalZero        """
1532*10465441SEvalZero        self._warn_for_redun_assign = True
1533*10465441SEvalZero
1534*10465441SEvalZero    def disable_redun_warnings(self):
1535*10465441SEvalZero        """
1536*10465441SEvalZero        See enable_redun_warnings().
1537*10465441SEvalZero        """
1538*10465441SEvalZero        self._warn_for_redun_assign = False
1539*10465441SEvalZero
1540*10465441SEvalZero    def __repr__(self):
1541*10465441SEvalZero        """
1542*10465441SEvalZero        Returns a string with information about the Kconfig object when it is
1543*10465441SEvalZero        evaluated on e.g. the interactive Python prompt.
1544*10465441SEvalZero        """
1545*10465441SEvalZero        return "<{}>".format(", ".join((
1546*10465441SEvalZero            "configuration with {} symbols".format(len(self.syms)),
1547*10465441SEvalZero            'main menu prompt "{}"'.format(self.mainmenu_text),
1548*10465441SEvalZero            "srctree is current directory" if not self.srctree else
1549*10465441SEvalZero                'srctree "{}"'.format(self.srctree),
1550*10465441SEvalZero            'config symbol prefix "{}"'.format(self.config_prefix),
1551*10465441SEvalZero            "warnings " +
1552*10465441SEvalZero                ("enabled" if self._warnings_enabled else "disabled"),
1553*10465441SEvalZero            "printing of warnings to stderr " +
1554*10465441SEvalZero                ("enabled" if self._warn_to_stderr else "disabled"),
1555*10465441SEvalZero            "undef. symbol assignment warnings " +
1556*10465441SEvalZero                ("enabled" if self._warn_for_undef_assign else "disabled"),
1557*10465441SEvalZero            "redundant symbol assignment warnings " +
1558*10465441SEvalZero                ("enabled" if self._warn_for_redun_assign else "disabled")
1559*10465441SEvalZero        )))
1560*10465441SEvalZero
1561*10465441SEvalZero    #
1562*10465441SEvalZero    # Private methods
1563*10465441SEvalZero    #
1564*10465441SEvalZero
1565*10465441SEvalZero
1566*10465441SEvalZero    #
1567*10465441SEvalZero    # File reading
1568*10465441SEvalZero    #
1569*10465441SEvalZero
1570*10465441SEvalZero    def _open_config(self, filename):
1571*10465441SEvalZero        # Opens a .config file. First tries to open 'filename', then
1572*10465441SEvalZero        # '$srctree/filename' if $srctree was set when the configuration was
1573*10465441SEvalZero        # loaded.
1574*10465441SEvalZero
1575*10465441SEvalZero        try:
1576*10465441SEvalZero            return self._open(filename, "r")
1577*10465441SEvalZero        except IOError as e:
1578*10465441SEvalZero            # This will try opening the same file twice if $srctree is unset,
1579*10465441SEvalZero            # but it's not a big deal
1580*10465441SEvalZero            try:
1581*10465441SEvalZero                return self._open(os.path.join(self.srctree, filename), "r")
1582*10465441SEvalZero            except IOError as e2:
1583*10465441SEvalZero                # This is needed for Python 3, because e2 is deleted after
1584*10465441SEvalZero                # the try block:
1585*10465441SEvalZero                #
1586*10465441SEvalZero                # https://docs.python.org/3/reference/compound_stmts.html#the-try-statement
1587*10465441SEvalZero                e = e2
1588*10465441SEvalZero
1589*10465441SEvalZero            raise IOError("\n" + textwrap.fill(
1590*10465441SEvalZero                "Could not open '{}' ({}: {}){}".format(
1591*10465441SEvalZero                    filename, errno.errorcode[e.errno], e.strerror,
1592*10465441SEvalZero                    self._srctree_hint()),
1593*10465441SEvalZero                80))
1594*10465441SEvalZero
1595*10465441SEvalZero    def _enter_file(self, full_filename, rel_filename):
1596*10465441SEvalZero        # Jumps to the beginning of a sourced Kconfig file, saving the previous
1597*10465441SEvalZero        # position and file object.
1598*10465441SEvalZero        #
1599*10465441SEvalZero        # full_filename:
1600*10465441SEvalZero        #   Actual path to the file.
1601*10465441SEvalZero        #
1602*10465441SEvalZero        # rel_filename:
1603*10465441SEvalZero        #   File path with $srctree prefix stripped, stored in e.g.
1604*10465441SEvalZero        #   self._filename (which makes it indirectly show up in
1605*10465441SEvalZero        #   MenuNode.filename). Equals full_filename for absolute paths.
1606*10465441SEvalZero
1607*10465441SEvalZero        self.kconfig_filenames.append(rel_filename)
1608*10465441SEvalZero
1609*10465441SEvalZero        # The parent Kconfig files are represented as a list of
1610*10465441SEvalZero        # (<include path>, <Python 'file' object for Kconfig file>) tuples.
1611*10465441SEvalZero        #
1612*10465441SEvalZero        # <include path> is immutable and holds a *tuple* of
1613*10465441SEvalZero        # (<filename>, <linenr>) tuples, giving the locations of the 'source'
1614*10465441SEvalZero        # statements in the parent Kconfig files. The current include path is
1615*10465441SEvalZero        # also available in Kconfig._include_path.
1616*10465441SEvalZero        #
1617*10465441SEvalZero        # The point of this redundant setup is to allow Kconfig._include_path
1618*10465441SEvalZero        # to be assigned directly to MenuNode.include_path without having to
1619*10465441SEvalZero        # copy it, sharing it wherever possible.
1620*10465441SEvalZero
1621*10465441SEvalZero        # Save include path and 'file' object before entering the file
1622*10465441SEvalZero        self._filestack.append((self._include_path, self._file))
1623*10465441SEvalZero
1624*10465441SEvalZero        # _include_path is a tuple, so this rebinds the variable instead of
1625*10465441SEvalZero        # doing in-place modification
1626*10465441SEvalZero        self._include_path += ((self._filename, self._linenr),)
1627*10465441SEvalZero
1628*10465441SEvalZero        # Check for recursive 'source'
1629*10465441SEvalZero        for name, _ in self._include_path:
1630*10465441SEvalZero            if name == rel_filename:
1631*10465441SEvalZero                raise KconfigError(
1632*10465441SEvalZero                    "\n{}:{}: Recursive 'source' of '{}' detected. Check that "
1633*10465441SEvalZero                    "environment variables are set correctly.\n"
1634*10465441SEvalZero                    "Include path:\n{}"
1635*10465441SEvalZero                    .format(self._filename, self._linenr, rel_filename,
1636*10465441SEvalZero                            "\n".join("{}:{}".format(name, linenr)
1637*10465441SEvalZero                                      for name, linenr in self._include_path)))
1638*10465441SEvalZero
1639*10465441SEvalZero        # Note: We already know that the file exists
1640*10465441SEvalZero
1641*10465441SEvalZero        try:
1642*10465441SEvalZero            self._file = self._open(full_filename, "r")
1643*10465441SEvalZero        except IOError as e:
1644*10465441SEvalZero            raise IOError("{}:{}: Could not open '{}' ({}: {})".format(
1645*10465441SEvalZero                self._filename, self._linenr, full_filename,
1646*10465441SEvalZero                errno.errorcode[e.errno], e.strerror))
1647*10465441SEvalZero
1648*10465441SEvalZero        self._filename = rel_filename
1649*10465441SEvalZero        self._linenr = 0
1650*10465441SEvalZero
1651*10465441SEvalZero    def _leave_file(self):
1652*10465441SEvalZero        # Returns from a Kconfig file to the file that sourced it. See
1653*10465441SEvalZero        # _enter_file().
1654*10465441SEvalZero
1655*10465441SEvalZero        self._file.close()
1656*10465441SEvalZero        # Restore location from parent Kconfig file
1657*10465441SEvalZero        self._filename, self._linenr = self._include_path[-1]
1658*10465441SEvalZero        # Restore include path and 'file' object
1659*10465441SEvalZero        self._include_path, self._file = self._filestack.pop()
1660*10465441SEvalZero
1661*10465441SEvalZero    def _next_line(self):
1662*10465441SEvalZero        # Fetches and tokenizes the next line from the current Kconfig file.
1663*10465441SEvalZero        # Returns False at EOF and True otherwise.
1664*10465441SEvalZero
1665*10465441SEvalZero        # _saved_line provides a single line of "unget", currently only used
1666*10465441SEvalZero        # for help texts.
1667*10465441SEvalZero        #
1668*10465441SEvalZero        # This also works as expected if _saved_line is "", indicating EOF:
1669*10465441SEvalZero        # "" is falsy, and readline() returns "" over and over at EOF.
1670*10465441SEvalZero        if self._saved_line:
1671*10465441SEvalZero            self._line = self._saved_line
1672*10465441SEvalZero            self._saved_line = None
1673*10465441SEvalZero        else:
1674*10465441SEvalZero            self._line = self._file.readline()
1675*10465441SEvalZero            if not self._line:
1676*10465441SEvalZero                return False
1677*10465441SEvalZero            self._linenr += 1
1678*10465441SEvalZero
1679*10465441SEvalZero        # Handle line joining
1680*10465441SEvalZero        while self._line.endswith("\\\n"):
1681*10465441SEvalZero            self._line = self._line[:-2] + self._file.readline()
1682*10465441SEvalZero            self._linenr += 1
1683*10465441SEvalZero
1684*10465441SEvalZero        self._tokens = self._tokenize(self._line)
1685*10465441SEvalZero        self._tokens_i = -1  # Token index (minus one)
1686*10465441SEvalZero
1687*10465441SEvalZero        return True
1688*10465441SEvalZero
1689*10465441SEvalZero
1690*10465441SEvalZero    #
1691*10465441SEvalZero    # Tokenization
1692*10465441SEvalZero    #
1693*10465441SEvalZero
1694*10465441SEvalZero    def _lookup_sym(self, name):
1695*10465441SEvalZero        # Fetches the symbol 'name' from the symbol table, creating and
1696*10465441SEvalZero        # registering it if it does not exist. If '_parsing_kconfigs' is False,
1697*10465441SEvalZero        # it means we're in eval_string(), and new symbols won't be registered.
1698*10465441SEvalZero
1699*10465441SEvalZero        if name in self.syms:
1700*10465441SEvalZero            return self.syms[name]
1701*10465441SEvalZero
1702*10465441SEvalZero        sym = Symbol()
1703*10465441SEvalZero        sym.kconfig = self
1704*10465441SEvalZero        sym.name = name
1705*10465441SEvalZero        sym.is_constant = False
1706*10465441SEvalZero        sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n
1707*10465441SEvalZero
1708*10465441SEvalZero        if self._parsing_kconfigs:
1709*10465441SEvalZero            self.syms[name] = sym
1710*10465441SEvalZero        else:
1711*10465441SEvalZero            self._warn("no symbol {} in configuration".format(name))
1712*10465441SEvalZero
1713*10465441SEvalZero        return sym
1714*10465441SEvalZero
1715*10465441SEvalZero    def _lookup_const_sym(self, name):
1716*10465441SEvalZero        # Like _lookup_sym(), for constant (quoted) symbols
1717*10465441SEvalZero
1718*10465441SEvalZero        if name in self.const_syms:
1719*10465441SEvalZero            return self.const_syms[name]
1720*10465441SEvalZero
1721*10465441SEvalZero        sym = Symbol()
1722*10465441SEvalZero        sym.kconfig = self
1723*10465441SEvalZero        sym.name = name
1724*10465441SEvalZero        sym.is_constant = True
1725*10465441SEvalZero        sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n
1726*10465441SEvalZero
1727*10465441SEvalZero        if self._parsing_kconfigs:
1728*10465441SEvalZero            self.const_syms[name] = sym
1729*10465441SEvalZero
1730*10465441SEvalZero        return sym
1731*10465441SEvalZero
1732*10465441SEvalZero    def _tokenize(self, s):
1733*10465441SEvalZero        # Parses 's', returning a None-terminated list of tokens. Registers any
1734*10465441SEvalZero        # new symbols encountered with _lookup(_const)_sym().
1735*10465441SEvalZero        #
1736*10465441SEvalZero        # Tries to be reasonably speedy by processing chunks of text via
1737*10465441SEvalZero        # regexes and string operations where possible. This is the biggest
1738*10465441SEvalZero        # hotspot during parsing.
1739*10465441SEvalZero        #
1740*10465441SEvalZero        # Note: It might be possible to rewrite this to 'yield' tokens instead,
1741*10465441SEvalZero        # working across multiple lines. The 'option env' lookback thing below
1742*10465441SEvalZero        # complicates things though.
1743*10465441SEvalZero
1744*10465441SEvalZero        # Initial token on the line
1745*10465441SEvalZero        match = _command_match(s)
1746*10465441SEvalZero        if not match:
1747*10465441SEvalZero            if s.isspace() or s.lstrip().startswith("#"):
1748*10465441SEvalZero                return (None,)
1749*10465441SEvalZero            self._parse_error("unknown token at start of line")
1750*10465441SEvalZero
1751*10465441SEvalZero        # Tricky implementation detail: While parsing a token, 'token' refers
1752*10465441SEvalZero        # to the previous token. See _STRING_LEX for why this is needed.
1753*10465441SEvalZero        token = _get_keyword(match.group(1))
1754*10465441SEvalZero        if not token:
1755*10465441SEvalZero            # Backwards compatibility with old versions of the C tools, which
1756*10465441SEvalZero            # (accidentally) accepted stuff like "--help--" and "-help---".
1757*10465441SEvalZero            # This was fixed in the C tools by commit c2264564 ("kconfig: warn
1758*10465441SEvalZero            # of unhandled characters in Kconfig commands"), committed in July
1759*10465441SEvalZero            # 2015, but it seems people still run Kconfiglib on older kernels.
1760*10465441SEvalZero            if s.strip(" \t\n-") == "help":
1761*10465441SEvalZero                return (_T_HELP, None)
1762*10465441SEvalZero
1763*10465441SEvalZero            # If the first token is not a keyword (and not a weird help token),
1764*10465441SEvalZero            # we have a preprocessor variable assignment (or a bare macro on a
1765*10465441SEvalZero            # line)
1766*10465441SEvalZero            self._parse_assignment(s)
1767*10465441SEvalZero            return (None,)
1768*10465441SEvalZero
1769*10465441SEvalZero        tokens = [token]
1770*10465441SEvalZero        # The current index in the string being tokenized
1771*10465441SEvalZero        i = match.end()
1772*10465441SEvalZero
1773*10465441SEvalZero        # Main tokenization loop (for tokens past the first one)
1774*10465441SEvalZero        while i < len(s):
1775*10465441SEvalZero            # Test for an identifier/keyword first. This is the most common
1776*10465441SEvalZero            # case.
1777*10465441SEvalZero            match = _id_keyword_match(s, i)
1778*10465441SEvalZero            if match:
1779*10465441SEvalZero                # We have an identifier or keyword
1780*10465441SEvalZero
1781*10465441SEvalZero                # Jump past it
1782*10465441SEvalZero                i = match.end()
1783*10465441SEvalZero
1784*10465441SEvalZero                # Check what it is. lookup_sym() will take care of allocating
1785*10465441SEvalZero                # new symbols for us the first time we see them. Note that
1786*10465441SEvalZero                # 'token' still refers to the previous token.
1787*10465441SEvalZero
1788*10465441SEvalZero                name = match.group(1)
1789*10465441SEvalZero                keyword = _get_keyword(name)
1790*10465441SEvalZero                if keyword:
1791*10465441SEvalZero                    # It's a keyword
1792*10465441SEvalZero                    token = keyword
1793*10465441SEvalZero
1794*10465441SEvalZero                elif token not in _STRING_LEX:
1795*10465441SEvalZero                    # It's a non-const symbol, except we translate n, m, and y
1796*10465441SEvalZero                    # into the corresponding constant symbols, like the C
1797*10465441SEvalZero                    # implementation
1798*10465441SEvalZero                    token = self.const_syms[name] \
1799*10465441SEvalZero                            if name in ("n", "m", "y") else \
1800*10465441SEvalZero                            self._lookup_sym(name)
1801*10465441SEvalZero
1802*10465441SEvalZero                else:
1803*10465441SEvalZero                    # It's a case of missing quotes. For example, the
1804*10465441SEvalZero                    # following is accepted:
1805*10465441SEvalZero                    #
1806*10465441SEvalZero                    #   menu unquoted_title
1807*10465441SEvalZero                    #
1808*10465441SEvalZero                    #   config A
1809*10465441SEvalZero                    #       tristate unquoted_prompt
1810*10465441SEvalZero                    #
1811*10465441SEvalZero                    #   endmenu
1812*10465441SEvalZero                    token = name
1813*10465441SEvalZero
1814*10465441SEvalZero            else:
1815*10465441SEvalZero                # Neither a keyword nor a non-const symbol (except
1816*10465441SEvalZero                # $()-expansion might still yield a non-const symbol).
1817*10465441SEvalZero
1818*10465441SEvalZero                # We always strip whitespace after tokens, so it is safe to
1819*10465441SEvalZero                # assume that s[i] is the start of a token here.
1820*10465441SEvalZero                c = s[i]
1821*10465441SEvalZero
1822*10465441SEvalZero                if c in "\"'":
1823*10465441SEvalZero                    s, end_i = self._expand_str(s, i, c)
1824*10465441SEvalZero
1825*10465441SEvalZero                    # os.path.expandvars() and the $UNAME_RELEASE replace() is
1826*10465441SEvalZero                    # a backwards compatibility hack, which should be
1827*10465441SEvalZero                    # reasonably safe as expandvars() leaves references to
1828*10465441SEvalZero                    # undefined env. vars. as is.
1829*10465441SEvalZero                    #
1830*10465441SEvalZero                    # The preprocessor functionality changed how environment
1831*10465441SEvalZero                    # variables are referenced, to $(FOO).
1832*10465441SEvalZero                    val = os.path.expandvars(
1833*10465441SEvalZero                        s[i + 1:end_i - 1].replace("$UNAME_RELEASE",
1834*10465441SEvalZero                                                   platform.uname()[2]))
1835*10465441SEvalZero
1836*10465441SEvalZero                    i = end_i
1837*10465441SEvalZero
1838*10465441SEvalZero                    # This is the only place where we don't survive with a
1839*10465441SEvalZero                    # single token of lookback: 'option env="FOO"' does not
1840*10465441SEvalZero                    # refer to a constant symbol named "FOO".
1841*10465441SEvalZero                    token = val \
1842*10465441SEvalZero                            if token in _STRING_LEX or \
1843*10465441SEvalZero                                tokens[0] is _T_OPTION else \
1844*10465441SEvalZero                            self._lookup_const_sym(val)
1845*10465441SEvalZero
1846*10465441SEvalZero                elif s.startswith("&&", i):
1847*10465441SEvalZero                    token = _T_AND
1848*10465441SEvalZero                    i += 2
1849*10465441SEvalZero
1850*10465441SEvalZero                elif s.startswith("||", i):
1851*10465441SEvalZero                    token = _T_OR
1852*10465441SEvalZero                    i += 2
1853*10465441SEvalZero
1854*10465441SEvalZero                elif c == "=":
1855*10465441SEvalZero                    token = _T_EQUAL
1856*10465441SEvalZero                    i += 1
1857*10465441SEvalZero
1858*10465441SEvalZero                elif s.startswith("!=", i):
1859*10465441SEvalZero                    token = _T_UNEQUAL
1860*10465441SEvalZero                    i += 2
1861*10465441SEvalZero
1862*10465441SEvalZero                elif c == "!":
1863*10465441SEvalZero                    token = _T_NOT
1864*10465441SEvalZero                    i += 1
1865*10465441SEvalZero
1866*10465441SEvalZero                elif c == "(":
1867*10465441SEvalZero                    token = _T_OPEN_PAREN
1868*10465441SEvalZero                    i += 1
1869*10465441SEvalZero
1870*10465441SEvalZero                elif c == ")":
1871*10465441SEvalZero                    token = _T_CLOSE_PAREN
1872*10465441SEvalZero                    i += 1
1873*10465441SEvalZero
1874*10465441SEvalZero                elif s.startswith("$(", i):
1875*10465441SEvalZero                    s, end_i = self._expand_macro(s, i, ())
1876*10465441SEvalZero                    val = s[i:end_i]
1877*10465441SEvalZero                    # isspace() is False for empty strings
1878*10465441SEvalZero                    if not val.strip():
1879*10465441SEvalZero                        # Avoid creating a Kconfig symbol with a blank name.
1880*10465441SEvalZero                        # It's almost guaranteed to be an error.
1881*10465441SEvalZero                        self._parse_error("macro expanded to blank string")
1882*10465441SEvalZero                    i = end_i
1883*10465441SEvalZero
1884*10465441SEvalZero                    # Compatibility with what the C implementation does. Might
1885*10465441SEvalZero                    # be unexpected that you can reference non-constant symbols
1886*10465441SEvalZero                    # this way though...
1887*10465441SEvalZero                    token = self.const_syms[val] \
1888*10465441SEvalZero                            if val in ("n", "m", "y") else \
1889*10465441SEvalZero                            self._lookup_sym(val)
1890*10465441SEvalZero
1891*10465441SEvalZero                elif s.startswith("$", i):
1892*10465441SEvalZero                    if token == _T_CONFIG:
1893*10465441SEvalZero                        s.replace('$', ' ')
1894*10465441SEvalZero                        i += 1
1895*10465441SEvalZero                        continue
1896*10465441SEvalZero                elif c == "#":
1897*10465441SEvalZero                    break
1898*10465441SEvalZero
1899*10465441SEvalZero
1900*10465441SEvalZero                # Very rare
1901*10465441SEvalZero
1902*10465441SEvalZero                elif s.startswith("<=", i):
1903*10465441SEvalZero                    token = _T_LESS_EQUAL
1904*10465441SEvalZero                    i += 2
1905*10465441SEvalZero
1906*10465441SEvalZero                elif c == "<":
1907*10465441SEvalZero                    token = _T_LESS
1908*10465441SEvalZero                    i += 1
1909*10465441SEvalZero
1910*10465441SEvalZero                elif s.startswith(">=", i):
1911*10465441SEvalZero                    token = _T_GREATER_EQUAL
1912*10465441SEvalZero                    i += 2
1913*10465441SEvalZero
1914*10465441SEvalZero                elif c == ">":
1915*10465441SEvalZero                    token = _T_GREATER
1916*10465441SEvalZero                    i += 1
1917*10465441SEvalZero
1918*10465441SEvalZero
1919*10465441SEvalZero                else:
1920*10465441SEvalZero                    self._parse_error("unknown tokens in line")
1921*10465441SEvalZero
1922*10465441SEvalZero
1923*10465441SEvalZero                # Skip trailing whitespace
1924*10465441SEvalZero                while i < len(s) and s[i].isspace():
1925*10465441SEvalZero                    i += 1
1926*10465441SEvalZero
1927*10465441SEvalZero
1928*10465441SEvalZero            # Add the token
1929*10465441SEvalZero            tokens.append(token)
1930*10465441SEvalZero
1931*10465441SEvalZero        # None-terminating the token list makes the token fetching functions
1932*10465441SEvalZero        # simpler/faster
1933*10465441SEvalZero        tokens.append(None)
1934*10465441SEvalZero
1935*10465441SEvalZero        return tokens
1936*10465441SEvalZero
1937*10465441SEvalZero    def _next_token(self):
1938*10465441SEvalZero        self._tokens_i += 1
1939*10465441SEvalZero        return self._tokens[self._tokens_i]
1940*10465441SEvalZero
1941*10465441SEvalZero    def _peek_token(self):
1942*10465441SEvalZero        return self._tokens[self._tokens_i + 1]
1943*10465441SEvalZero
1944*10465441SEvalZero    # The functions below are just _next_token() and _parse_expr() with extra
1945*10465441SEvalZero    # syntax checking. Inlining _next_token() and _peek_token() into them saves
1946*10465441SEvalZero    # a few % of parsing time.
1947*10465441SEvalZero    #
1948*10465441SEvalZero    # See the 'Intro to expressions' section for what a constant symbol is.
1949*10465441SEvalZero
1950*10465441SEvalZero    def _expect_sym(self):
1951*10465441SEvalZero        self._tokens_i += 1
1952*10465441SEvalZero        token = self._tokens[self._tokens_i]
1953*10465441SEvalZero
1954*10465441SEvalZero        if not isinstance(token, Symbol):
1955*10465441SEvalZero            self._parse_error("expected symbol")
1956*10465441SEvalZero
1957*10465441SEvalZero        return token
1958*10465441SEvalZero
1959*10465441SEvalZero    def _expect_nonconst_sym(self):
1960*10465441SEvalZero        self._tokens_i += 1
1961*10465441SEvalZero        token = self._tokens[self._tokens_i]
1962*10465441SEvalZero
1963*10465441SEvalZero        if not isinstance(token, Symbol) or token.is_constant:
1964*10465441SEvalZero            self._parse_error("expected nonconstant symbol")
1965*10465441SEvalZero
1966*10465441SEvalZero        return token
1967*10465441SEvalZero
1968*10465441SEvalZero    def _expect_nonconst_sym_and_eol(self):
1969*10465441SEvalZero        self._tokens_i += 1
1970*10465441SEvalZero        token = self._tokens[self._tokens_i]
1971*10465441SEvalZero
1972*10465441SEvalZero        if not isinstance(token, Symbol) or token.is_constant:
1973*10465441SEvalZero            self._parse_error("expected nonconstant symbol")
1974*10465441SEvalZero
1975*10465441SEvalZero        if self._tokens[self._tokens_i + 1] is not None:
1976*10465441SEvalZero            self._parse_error("extra tokens at end of line")
1977*10465441SEvalZero
1978*10465441SEvalZero        return token
1979*10465441SEvalZero
1980*10465441SEvalZero    def _expect_str(self):
1981*10465441SEvalZero        self._tokens_i += 1
1982*10465441SEvalZero        token = self._tokens[self._tokens_i]
1983*10465441SEvalZero
1984*10465441SEvalZero        if not isinstance(token, str):
1985*10465441SEvalZero            self._parse_error("expected string")
1986*10465441SEvalZero
1987*10465441SEvalZero        return token
1988*10465441SEvalZero
1989*10465441SEvalZero    def _expect_str_and_eol(self):
1990*10465441SEvalZero        self._tokens_i += 1
1991*10465441SEvalZero        token = self._tokens[self._tokens_i]
1992*10465441SEvalZero
1993*10465441SEvalZero        if not isinstance(token, str):
1994*10465441SEvalZero            self._parse_error("expected string")
1995*10465441SEvalZero
1996*10465441SEvalZero        if self._tokens[self._tokens_i + 1] is not None:
1997*10465441SEvalZero            self._parse_error("extra tokens at end of line")
1998*10465441SEvalZero
1999*10465441SEvalZero        return token
2000*10465441SEvalZero
2001*10465441SEvalZero    def _expect_expr_and_eol(self):
2002*10465441SEvalZero        expr = self._parse_expr(True)
2003*10465441SEvalZero
2004*10465441SEvalZero        if self._peek_token() is not None:
2005*10465441SEvalZero            self._parse_error("extra tokens at end of line")
2006*10465441SEvalZero
2007*10465441SEvalZero        return expr
2008*10465441SEvalZero
2009*10465441SEvalZero    def _check_token(self, token):
2010*10465441SEvalZero        # If the next token is 'token', removes it and returns True
2011*10465441SEvalZero
2012*10465441SEvalZero        if self._tokens[self._tokens_i + 1] is token:
2013*10465441SEvalZero            self._tokens_i += 1
2014*10465441SEvalZero            return True
2015*10465441SEvalZero        return False
2016*10465441SEvalZero
2017*10465441SEvalZero
2018*10465441SEvalZero    #
2019*10465441SEvalZero    # Preprocessor logic
2020*10465441SEvalZero    #
2021*10465441SEvalZero
2022*10465441SEvalZero    def _parse_assignment(self, s):
2023*10465441SEvalZero        # Parses a preprocessor variable assignment, registering the variable
2024*10465441SEvalZero        # if it doesn't already exist. Also takes care of bare macros on lines
2025*10465441SEvalZero        # (which are allowed, and can be useful for their side effects).
2026*10465441SEvalZero
2027*10465441SEvalZero        # Expand any macros in the left-hand side of the assignment (the
2028*10465441SEvalZero        # variable name)
2029*10465441SEvalZero        s = s.lstrip()
2030*10465441SEvalZero        i = 0
2031*10465441SEvalZero        while 1:
2032*10465441SEvalZero            i = _assignment_lhs_fragment_match(s, i).end()
2033*10465441SEvalZero            if s.startswith("$(", i):
2034*10465441SEvalZero                s, i = self._expand_macro(s, i, ())
2035*10465441SEvalZero            else:
2036*10465441SEvalZero                break
2037*10465441SEvalZero
2038*10465441SEvalZero        if s.isspace():
2039*10465441SEvalZero            # We also accept a bare macro on a line (e.g.
2040*10465441SEvalZero            # $(warning-if,$(foo),ops)), provided it expands to a blank string
2041*10465441SEvalZero            return
2042*10465441SEvalZero
2043*10465441SEvalZero        # Assigned variable
2044*10465441SEvalZero        name = s[:i]
2045*10465441SEvalZero
2046*10465441SEvalZero
2047*10465441SEvalZero        # Extract assignment operator (=, :=, or +=) and value
2048*10465441SEvalZero        rhs_match = _assignment_rhs_match(s, i)
2049*10465441SEvalZero        if not rhs_match:
2050*10465441SEvalZero            self._parse_error("syntax error")
2051*10465441SEvalZero
2052*10465441SEvalZero        op, val = rhs_match.groups()
2053*10465441SEvalZero
2054*10465441SEvalZero
2055*10465441SEvalZero        if name in self.variables:
2056*10465441SEvalZero            # Already seen variable
2057*10465441SEvalZero            var = self.variables[name]
2058*10465441SEvalZero        else:
2059*10465441SEvalZero            # New variable
2060*10465441SEvalZero            var = Variable()
2061*10465441SEvalZero            var.kconfig = self
2062*10465441SEvalZero            var.name = name
2063*10465441SEvalZero            var._n_expansions = 0
2064*10465441SEvalZero            self.variables[name] = var
2065*10465441SEvalZero
2066*10465441SEvalZero            # += acts like = on undefined variables (defines a recursive
2067*10465441SEvalZero            # variable)
2068*10465441SEvalZero            if op == "+=":
2069*10465441SEvalZero                op = "="
2070*10465441SEvalZero
2071*10465441SEvalZero        if op == "=":
2072*10465441SEvalZero            var.is_recursive = True
2073*10465441SEvalZero            var.value = val
2074*10465441SEvalZero        elif op == ":=":
2075*10465441SEvalZero            var.is_recursive = False
2076*10465441SEvalZero            var.value = self._expand_whole(val, ())
2077*10465441SEvalZero        else:  # op == "+="
2078*10465441SEvalZero            # += does immediate expansion if the variable was last set
2079*10465441SEvalZero            # with :=
2080*10465441SEvalZero            var.value += " " + (val if var.is_recursive else \
2081*10465441SEvalZero                                self._expand_whole(val, ()))
2082*10465441SEvalZero
2083*10465441SEvalZero    def _expand_whole(self, s, args):
2084*10465441SEvalZero        # Expands preprocessor macros in all of 's'. Used whenever we don't
2085*10465441SEvalZero        # have to worry about delimiters. See _expand_macro() re. the 'args'
2086*10465441SEvalZero        # parameter.
2087*10465441SEvalZero        #
2088*10465441SEvalZero        # Returns the expanded string.
2089*10465441SEvalZero
2090*10465441SEvalZero        i = 0
2091*10465441SEvalZero        while 1:
2092*10465441SEvalZero            i = s.find("$(", i)
2093*10465441SEvalZero            if i == -1:
2094*10465441SEvalZero                break
2095*10465441SEvalZero            s, i = self._expand_macro(s, i, args)
2096*10465441SEvalZero        return s
2097*10465441SEvalZero
2098*10465441SEvalZero    def _expand_str(self, s, i, quote):
2099*10465441SEvalZero        # Expands a quoted string starting at index 'i' in 's'. Handles both
2100*10465441SEvalZero        # backslash escapes and macro expansion.
2101*10465441SEvalZero        #
2102*10465441SEvalZero        # Returns the expanded 's' (including the part before the string) and
2103*10465441SEvalZero        # the index of the first character after the expanded string in 's'.
2104*10465441SEvalZero
2105*10465441SEvalZero        i += 1  # Skip over initial "/'
2106*10465441SEvalZero        while 1:
2107*10465441SEvalZero            match = _string_special_search(s, i)
2108*10465441SEvalZero            if not match:
2109*10465441SEvalZero                self._parse_error("unterminated string")
2110*10465441SEvalZero
2111*10465441SEvalZero
2112*10465441SEvalZero            if match.group() == quote:
2113*10465441SEvalZero                # Found the end of the string
2114*10465441SEvalZero                return (s, match.end())
2115*10465441SEvalZero
2116*10465441SEvalZero            elif match.group() == "\\":
2117*10465441SEvalZero                # Replace '\x' with 'x'. 'i' ends up pointing to the character
2118*10465441SEvalZero                # after 'x', which allows macros to be canceled with '\$(foo)'.
2119*10465441SEvalZero                i = match.end()
2120*10465441SEvalZero                s = s[:match.start()] + s[i:]
2121*10465441SEvalZero
2122*10465441SEvalZero            elif match.group() == "$(":
2123*10465441SEvalZero                # A macro call within the string
2124*10465441SEvalZero                s, i = self._expand_macro(s, match.start(), ())
2125*10465441SEvalZero
2126*10465441SEvalZero            else:
2127*10465441SEvalZero                # A ' quote within " quotes or vice versa
2128*10465441SEvalZero                i += 1
2129*10465441SEvalZero
2130*10465441SEvalZero    def _expand_macro(self, s, i, args):
2131*10465441SEvalZero        # Expands a macro starting at index 'i' in 's'. If this macro resulted
2132*10465441SEvalZero        # from the expansion of another macro, 'args' holds the arguments
2133*10465441SEvalZero        # passed to that macro.
2134*10465441SEvalZero        #
2135*10465441SEvalZero        # Returns the expanded 's' (including the part before the macro) and
2136*10465441SEvalZero        # the index of the first character after the expanded macro in 's'.
2137*10465441SEvalZero
2138*10465441SEvalZero        start = i
2139*10465441SEvalZero        i += 2  # Skip over "$("
2140*10465441SEvalZero
2141*10465441SEvalZero        # Start of current macro argument
2142*10465441SEvalZero        arg_start = i
2143*10465441SEvalZero
2144*10465441SEvalZero        # Arguments of this macro call
2145*10465441SEvalZero        new_args = []
2146*10465441SEvalZero
2147*10465441SEvalZero        while 1:
2148*10465441SEvalZero            match = _macro_special_search(s, i)
2149*10465441SEvalZero            if not match:
2150*10465441SEvalZero                self._parse_error("missing end parenthesis in macro expansion")
2151*10465441SEvalZero
2152*10465441SEvalZero
2153*10465441SEvalZero            if match.group() == ")":
2154*10465441SEvalZero                # Found the end of the macro
2155*10465441SEvalZero
2156*10465441SEvalZero                new_args.append(s[arg_start:match.start()])
2157*10465441SEvalZero
2158*10465441SEvalZero                prefix = s[:start]
2159*10465441SEvalZero
2160*10465441SEvalZero                # $(1) is replaced by the first argument to the function, etc.,
2161*10465441SEvalZero                # provided at least that many arguments were passed
2162*10465441SEvalZero
2163*10465441SEvalZero                try:
2164*10465441SEvalZero                    # Does the macro look like an integer, with a corresponding
2165*10465441SEvalZero                    # argument? If so, expand it to the value of the argument.
2166*10465441SEvalZero                    prefix += args[int(new_args[0])]
2167*10465441SEvalZero                except (ValueError, IndexError):
2168*10465441SEvalZero                    # Regular variables are just functions without arguments,
2169*10465441SEvalZero                    # and also go through the function value path
2170*10465441SEvalZero                    prefix += self._fn_val(new_args)
2171*10465441SEvalZero
2172*10465441SEvalZero                return (prefix + s[match.end():],
2173*10465441SEvalZero                        len(prefix))
2174*10465441SEvalZero
2175*10465441SEvalZero            elif match.group() == ",":
2176*10465441SEvalZero                # Found the end of a macro argument
2177*10465441SEvalZero                new_args.append(s[arg_start:match.start()])
2178*10465441SEvalZero                arg_start = i = match.end()
2179*10465441SEvalZero
2180*10465441SEvalZero            else:  # match.group() == "$("
2181*10465441SEvalZero                # A nested macro call within the macro
2182*10465441SEvalZero                s, i = self._expand_macro(s, match.start(), args)
2183*10465441SEvalZero
2184*10465441SEvalZero    def _fn_val(self, args):
2185*10465441SEvalZero        # Returns the result of calling the function args[0] with the arguments
2186*10465441SEvalZero        # args[1..len(args)-1]. Plain variables are treated as functions
2187*10465441SEvalZero        # without arguments.
2188*10465441SEvalZero
2189*10465441SEvalZero        fn = args[0]
2190*10465441SEvalZero
2191*10465441SEvalZero        if fn in self.variables:
2192*10465441SEvalZero            var = self.variables[fn]
2193*10465441SEvalZero
2194*10465441SEvalZero            if len(args) == 1:
2195*10465441SEvalZero                # Plain variable
2196*10465441SEvalZero                if var._n_expansions:
2197*10465441SEvalZero                    self._parse_error("Preprocessor variable {} recursively "
2198*10465441SEvalZero                                      "references itself".format(var.name))
2199*10465441SEvalZero            elif var._n_expansions > 100:
2200*10465441SEvalZero                # Allow functions to call themselves, but guess that functions
2201*10465441SEvalZero                # that are overly recursive are stuck
2202*10465441SEvalZero                self._parse_error("Preprocessor function {} seems stuck "
2203*10465441SEvalZero                                  "in infinite recursion".format(var.name))
2204*10465441SEvalZero
2205*10465441SEvalZero            var._n_expansions += 1
2206*10465441SEvalZero            res = self._expand_whole(self.variables[fn].value, args)
2207*10465441SEvalZero            var._n_expansions -= 1
2208*10465441SEvalZero            return res
2209*10465441SEvalZero
2210*10465441SEvalZero        if fn in self._functions:
2211*10465441SEvalZero            # Built-in function
2212*10465441SEvalZero
2213*10465441SEvalZero            py_fn, min_arg, max_arg = self._functions[fn]
2214*10465441SEvalZero
2215*10465441SEvalZero            if not min_arg <= len(args) - 1 <= max_arg:
2216*10465441SEvalZero                if min_arg == max_arg:
2217*10465441SEvalZero                    expected_args = min_arg
2218*10465441SEvalZero                else:
2219*10465441SEvalZero                    expected_args = "{}-{}".format(min_arg, max_arg)
2220*10465441SEvalZero
2221*10465441SEvalZero                raise KconfigError("{}:{}: bad number of arguments in call "
2222*10465441SEvalZero                                   "to {}, expected {}, got {}"
2223*10465441SEvalZero                                   .format(self._filename, self._linenr, fn,
2224*10465441SEvalZero                                           expected_args, len(args) - 1))
2225*10465441SEvalZero
2226*10465441SEvalZero            return py_fn(self, args)
2227*10465441SEvalZero
2228*10465441SEvalZero        # Environment variables are tried last
2229*10465441SEvalZero        if fn in os.environ:
2230*10465441SEvalZero            self.env_vars.add(fn)
2231*10465441SEvalZero            return os.environ[fn]
2232*10465441SEvalZero
2233*10465441SEvalZero        return ""
2234*10465441SEvalZero
2235*10465441SEvalZero
2236*10465441SEvalZero    #
2237*10465441SEvalZero    # Parsing
2238*10465441SEvalZero    #
2239*10465441SEvalZero
2240*10465441SEvalZero    def _make_and(self, e1, e2):
2241*10465441SEvalZero        # Constructs an AND (&&) expression. Performs trivial simplification.
2242*10465441SEvalZero
2243*10465441SEvalZero        if e1 is self.y:
2244*10465441SEvalZero            return e2
2245*10465441SEvalZero
2246*10465441SEvalZero        if e2 is self.y:
2247*10465441SEvalZero            return e1
2248*10465441SEvalZero
2249*10465441SEvalZero        if e1 is self.n or e2 is self.n:
2250*10465441SEvalZero            return self.n
2251*10465441SEvalZero
2252*10465441SEvalZero        return (AND, e1, e2)
2253*10465441SEvalZero
2254*10465441SEvalZero    def _make_or(self, e1, e2):
2255*10465441SEvalZero        # Constructs an OR (||) expression. Performs trivial simplification.
2256*10465441SEvalZero
2257*10465441SEvalZero        if e1 is self.n:
2258*10465441SEvalZero            return e2
2259*10465441SEvalZero
2260*10465441SEvalZero        if e2 is self.n:
2261*10465441SEvalZero            return e1
2262*10465441SEvalZero
2263*10465441SEvalZero        if e1 is self.y or e2 is self.y:
2264*10465441SEvalZero            return self.y
2265*10465441SEvalZero
2266*10465441SEvalZero        return (OR, e1, e2)
2267*10465441SEvalZero
2268*10465441SEvalZero    def _parse_block(self, end_token, parent, prev):
2269*10465441SEvalZero        # Parses a block, which is the contents of either a file or an if,
2270*10465441SEvalZero        # menu, or choice statement.
2271*10465441SEvalZero        #
2272*10465441SEvalZero        # end_token:
2273*10465441SEvalZero        #   The token that ends the block, e.g. _T_ENDIF ("endif") for ifs.
2274*10465441SEvalZero        #   None for files.
2275*10465441SEvalZero        #
2276*10465441SEvalZero        # parent:
2277*10465441SEvalZero        #   The parent menu node, corresponding to a menu, Choice, or 'if'.
2278*10465441SEvalZero        #   'if's are flattened after parsing.
2279*10465441SEvalZero        #
2280*10465441SEvalZero        # prev:
2281*10465441SEvalZero        #   The previous menu node. New nodes will be added after this one (by
2282*10465441SEvalZero        #   modifying their 'next' pointer).
2283*10465441SEvalZero        #
2284*10465441SEvalZero        #   'prev' is reused to parse a list of child menu nodes (for a menu or
2285*10465441SEvalZero        #   Choice): After parsing the children, the 'next' pointer is assigned
2286*10465441SEvalZero        #   to the 'list' pointer to "tilt up" the children above the node.
2287*10465441SEvalZero        #
2288*10465441SEvalZero        # Returns the final menu node in the block (or 'prev' if the block is
2289*10465441SEvalZero        # empty). This allows chaining.
2290*10465441SEvalZero
2291*10465441SEvalZero        # We might already have tokens from parsing a line to check if it's a
2292*10465441SEvalZero        # property and discovering it isn't. self._has_tokens functions as a
2293*10465441SEvalZero        # kind of "unget".
2294*10465441SEvalZero        while self._has_tokens or self._next_line():
2295*10465441SEvalZero            self._has_tokens = False
2296*10465441SEvalZero
2297*10465441SEvalZero            t0 = self._next_token()
2298*10465441SEvalZero            if t0 is None:
2299*10465441SEvalZero                continue
2300*10465441SEvalZero
2301*10465441SEvalZero            if t0 in (_T_CONFIG, _T_MENUCONFIG):
2302*10465441SEvalZero                # The tokenizer allocates Symbol objects for us
2303*10465441SEvalZero                sym = self._expect_nonconst_sym_and_eol()
2304*10465441SEvalZero                self.defined_syms.append(sym)
2305*10465441SEvalZero
2306*10465441SEvalZero                node = MenuNode()
2307*10465441SEvalZero                node.kconfig = self
2308*10465441SEvalZero                node.item = sym
2309*10465441SEvalZero                node.is_menuconfig = (t0 is _T_MENUCONFIG)
2310*10465441SEvalZero                node.prompt = node.help = node.list = None
2311*10465441SEvalZero                node.parent = parent
2312*10465441SEvalZero                node.filename = self._filename
2313*10465441SEvalZero                node.linenr = self._linenr
2314*10465441SEvalZero                node.include_path = self._include_path
2315*10465441SEvalZero
2316*10465441SEvalZero                sym.nodes.append(node)
2317*10465441SEvalZero
2318*10465441SEvalZero                self._parse_properties(node)
2319*10465441SEvalZero
2320*10465441SEvalZero                if node.item.env_var:
2321*10465441SEvalZero                    if node.item.env_var in os.environ:
2322*10465441SEvalZero                        os.environ[node.item.name] = os.environ[node.item.env_var]
2323*10465441SEvalZero                    else:
2324*10465441SEvalZero                        os.environ[node.item.name] = ((node.defaults[0])[0]).name
2325*10465441SEvalZero
2326*10465441SEvalZero                if node.is_menuconfig and not node.prompt:
2327*10465441SEvalZero                    self._warn("the menuconfig symbol {} has no prompt"
2328*10465441SEvalZero                               .format(_name_and_loc(sym)))
2329*10465441SEvalZero
2330*10465441SEvalZero                # Tricky Python semantics: This assigns prev.next before prev
2331*10465441SEvalZero                prev.next = prev = node
2332*10465441SEvalZero
2333*10465441SEvalZero            elif t0 in (_T_SOURCE, _T_RSOURCE, _T_OSOURCE, _T_ORSOURCE):
2334*10465441SEvalZero                pattern = self._expect_str_and_eol()
2335*10465441SEvalZero
2336*10465441SEvalZero                # Check if the pattern is absolute and avoid stripping srctree
2337*10465441SEvalZero                # from it below in that case. We must do the check before
2338*10465441SEvalZero                # join()'ing, as srctree might be an absolute path.
2339*10465441SEvalZero                isabs = os.path.isabs(pattern)
2340*10465441SEvalZero
2341*10465441SEvalZero                if t0 in (_T_RSOURCE, _T_ORSOURCE):
2342*10465441SEvalZero                    # Relative source
2343*10465441SEvalZero                    pattern = os.path.join(os.path.dirname(self._filename),
2344*10465441SEvalZero                                           pattern)
2345*10465441SEvalZero
2346*10465441SEvalZero                # Sort the glob results to ensure a consistent ordering of
2347*10465441SEvalZero                # Kconfig symbols, which indirectly ensures a consistent
2348*10465441SEvalZero                # ordering in e.g. .config files
2349*10465441SEvalZero                filenames = \
2350*10465441SEvalZero                    sorted(glob.iglob(os.path.join(self.srctree, pattern)))
2351*10465441SEvalZero
2352*10465441SEvalZero                if not filenames and t0 in (_T_SOURCE, _T_RSOURCE):
2353*10465441SEvalZero                    raise KconfigError("\n" + textwrap.fill(
2354*10465441SEvalZero                        "{}:{}: '{}' does not exist{}".format(
2355*10465441SEvalZero                            self._filename, self._linenr, pattern,
2356*10465441SEvalZero                            self._srctree_hint()),
2357*10465441SEvalZero                        80))
2358*10465441SEvalZero
2359*10465441SEvalZero                for filename in filenames:
2360*10465441SEvalZero                    self._enter_file(
2361*10465441SEvalZero                        filename,
2362*10465441SEvalZero                        # Unless an absolute path is passed to *source, strip
2363*10465441SEvalZero                        # the $srctree prefix from the filename. That way it
2364*10465441SEvalZero                        # appears without a $srctree prefix in
2365*10465441SEvalZero                        # MenuNode.filename, which is nice e.g. when generating
2366*10465441SEvalZero                        # documentation.
2367*10465441SEvalZero                        filename if isabs else
2368*10465441SEvalZero                            os.path.relpath(filename, self.srctree))
2369*10465441SEvalZero
2370*10465441SEvalZero                    prev = self._parse_block(None, parent, prev)
2371*10465441SEvalZero
2372*10465441SEvalZero                    self._leave_file()
2373*10465441SEvalZero
2374*10465441SEvalZero            elif t0 is end_token:
2375*10465441SEvalZero                # We have reached the end of the block. Terminate the final
2376*10465441SEvalZero                # node and return it.
2377*10465441SEvalZero                prev.next = None
2378*10465441SEvalZero                return prev
2379*10465441SEvalZero
2380*10465441SEvalZero            elif t0 is _T_IF:
2381*10465441SEvalZero                node = MenuNode()
2382*10465441SEvalZero                node.item = node.prompt = None
2383*10465441SEvalZero                node.parent = parent
2384*10465441SEvalZero                node.filename = self._filename
2385*10465441SEvalZero                node.linenr = self._linenr
2386*10465441SEvalZero
2387*10465441SEvalZero                node.dep = self._expect_expr_and_eol()
2388*10465441SEvalZero
2389*10465441SEvalZero                self._parse_block(_T_ENDIF, node, node)
2390*10465441SEvalZero                node.list = node.next
2391*10465441SEvalZero
2392*10465441SEvalZero                prev.next = prev = node
2393*10465441SEvalZero
2394*10465441SEvalZero            elif t0 is _T_MENU:
2395*10465441SEvalZero                node = MenuNode()
2396*10465441SEvalZero                node.kconfig = self
2397*10465441SEvalZero                node.item = MENU
2398*10465441SEvalZero                node.is_menuconfig = True
2399*10465441SEvalZero                node.prompt = (self._expect_str_and_eol(), self.y)
2400*10465441SEvalZero                node.visibility = self.y
2401*10465441SEvalZero                node.parent = parent
2402*10465441SEvalZero                node.filename = self._filename
2403*10465441SEvalZero                node.linenr = self._linenr
2404*10465441SEvalZero                node.include_path = self._include_path
2405*10465441SEvalZero
2406*10465441SEvalZero                self.menus.append(node)
2407*10465441SEvalZero
2408*10465441SEvalZero                self._parse_properties(node)
2409*10465441SEvalZero                self._parse_block(_T_ENDMENU, node, node)
2410*10465441SEvalZero                node.list = node.next
2411*10465441SEvalZero
2412*10465441SEvalZero                prev.next = prev = node
2413*10465441SEvalZero
2414*10465441SEvalZero            elif t0 is _T_COMMENT:
2415*10465441SEvalZero                node = MenuNode()
2416*10465441SEvalZero                node.kconfig = self
2417*10465441SEvalZero                node.item = COMMENT
2418*10465441SEvalZero                node.is_menuconfig = False
2419*10465441SEvalZero                node.prompt = (self._expect_str_and_eol(), self.y)
2420*10465441SEvalZero                node.list = None
2421*10465441SEvalZero                node.parent = parent
2422*10465441SEvalZero                node.filename = self._filename
2423*10465441SEvalZero                node.linenr = self._linenr
2424*10465441SEvalZero                node.include_path = self._include_path
2425*10465441SEvalZero
2426*10465441SEvalZero                self.comments.append(node)
2427*10465441SEvalZero
2428*10465441SEvalZero                self._parse_properties(node)
2429*10465441SEvalZero
2430*10465441SEvalZero                prev.next = prev = node
2431*10465441SEvalZero
2432*10465441SEvalZero            elif t0 is _T_CHOICE:
2433*10465441SEvalZero                if self._peek_token() is None:
2434*10465441SEvalZero                    choice = Choice()
2435*10465441SEvalZero                    choice.direct_dep = self.n
2436*10465441SEvalZero
2437*10465441SEvalZero                    self.choices.append(choice)
2438*10465441SEvalZero                else:
2439*10465441SEvalZero                    # Named choice
2440*10465441SEvalZero                    name = self._expect_str_and_eol()
2441*10465441SEvalZero                    choice = self.named_choices.get(name)
2442*10465441SEvalZero                    if not choice:
2443*10465441SEvalZero                        choice = Choice()
2444*10465441SEvalZero                        choice.name = name
2445*10465441SEvalZero                        choice.direct_dep = self.n
2446*10465441SEvalZero
2447*10465441SEvalZero                        self.choices.append(choice)
2448*10465441SEvalZero                        self.named_choices[name] = choice
2449*10465441SEvalZero
2450*10465441SEvalZero                choice.kconfig = self
2451*10465441SEvalZero
2452*10465441SEvalZero                node = MenuNode()
2453*10465441SEvalZero                node.kconfig = self
2454*10465441SEvalZero                node.item = choice
2455*10465441SEvalZero                node.is_menuconfig = True
2456*10465441SEvalZero                node.prompt = node.help = None
2457*10465441SEvalZero                node.parent = parent
2458*10465441SEvalZero                node.filename = self._filename
2459*10465441SEvalZero                node.linenr = self._linenr
2460*10465441SEvalZero                node.include_path = self._include_path
2461*10465441SEvalZero
2462*10465441SEvalZero                choice.nodes.append(node)
2463*10465441SEvalZero
2464*10465441SEvalZero                self._parse_properties(node)
2465*10465441SEvalZero                self._parse_block(_T_ENDCHOICE, node, node)
2466*10465441SEvalZero                node.list = node.next
2467*10465441SEvalZero
2468*10465441SEvalZero                prev.next = prev = node
2469*10465441SEvalZero
2470*10465441SEvalZero            elif t0 is _T_MAINMENU:
2471*10465441SEvalZero                self.top_node.prompt = (self._expect_str_and_eol(), self.y)
2472*10465441SEvalZero                self.top_node.filename = self._filename
2473*10465441SEvalZero                self.top_node.linenr = self._linenr
2474*10465441SEvalZero
2475*10465441SEvalZero            else:
2476*10465441SEvalZero                self._parse_error("unrecognized construct")
2477*10465441SEvalZero
2478*10465441SEvalZero        # End of file reached. Terminate the final node and return it.
2479*10465441SEvalZero
2480*10465441SEvalZero        if end_token:
2481*10465441SEvalZero            raise KconfigError("Unexpected end of file " + self._filename)
2482*10465441SEvalZero
2483*10465441SEvalZero        prev.next = None
2484*10465441SEvalZero        return prev
2485*10465441SEvalZero
2486*10465441SEvalZero    def _parse_cond(self):
2487*10465441SEvalZero        # Parses an optional 'if <expr>' construct and returns the parsed
2488*10465441SEvalZero        # <expr>, or self.y if the next token is not _T_IF
2489*10465441SEvalZero
2490*10465441SEvalZero        return self._expect_expr_and_eol() if self._check_token(_T_IF) \
2491*10465441SEvalZero            else self.y
2492*10465441SEvalZero
2493*10465441SEvalZero    def _parse_properties(self, node):
2494*10465441SEvalZero        # Parses and adds properties to the MenuNode 'node' (type, 'prompt',
2495*10465441SEvalZero        # 'default's, etc.) Properties are later copied up to symbols and
2496*10465441SEvalZero        # choices in a separate pass after parsing, in _add_props_to_sc().
2497*10465441SEvalZero        #
2498*10465441SEvalZero        # An older version of this code added properties directly to symbols
2499*10465441SEvalZero        # and choices instead of to their menu nodes (and handled dependency
2500*10465441SEvalZero        # propagation simultaneously), but that loses information on where a
2501*10465441SEvalZero        # property is added when a symbol or choice is defined in multiple
2502*10465441SEvalZero        # locations. Some Kconfig configuration systems rely heavily on such
2503*10465441SEvalZero        # symbols, and better docs can be generated by keeping track of where
2504*10465441SEvalZero        # properties are added.
2505*10465441SEvalZero        #
2506*10465441SEvalZero        # node:
2507*10465441SEvalZero        #   The menu node we're parsing properties on
2508*10465441SEvalZero
2509*10465441SEvalZero        # Dependencies from 'depends on'. Will get propagated to the properties
2510*10465441SEvalZero        # below.
2511*10465441SEvalZero        node.dep = self.y
2512*10465441SEvalZero
2513*10465441SEvalZero        while self._next_line():
2514*10465441SEvalZero            t0 = self._next_token()
2515*10465441SEvalZero            if t0 is None:
2516*10465441SEvalZero                continue
2517*10465441SEvalZero
2518*10465441SEvalZero            if t0 in _TYPE_TOKENS:
2519*10465441SEvalZero                self._set_type(node, _TOKEN_TO_TYPE[t0])
2520*10465441SEvalZero                if self._peek_token() is not None:
2521*10465441SEvalZero                    self._parse_prompt(node)
2522*10465441SEvalZero
2523*10465441SEvalZero            elif t0 is _T_DEPENDS:
2524*10465441SEvalZero                if not self._check_token(_T_ON):
2525*10465441SEvalZero                    self._parse_error('expected "on" after "depends"')
2526*10465441SEvalZero
2527*10465441SEvalZero                node.dep = self._make_and(node.dep,
2528*10465441SEvalZero                                          self._expect_expr_and_eol())
2529*10465441SEvalZero
2530*10465441SEvalZero            elif t0 is _T_HELP:
2531*10465441SEvalZero                self._parse_help(node)
2532*10465441SEvalZero
2533*10465441SEvalZero            elif t0 is _T_SELECT:
2534*10465441SEvalZero                if not isinstance(node.item, Symbol):
2535*10465441SEvalZero                    self._parse_error("only symbols can select")
2536*10465441SEvalZero
2537*10465441SEvalZero                node.selects.append((self._expect_nonconst_sym(),
2538*10465441SEvalZero                                     self._parse_cond()))
2539*10465441SEvalZero
2540*10465441SEvalZero            elif t0 is _T_IMPLY:
2541*10465441SEvalZero                if not isinstance(node.item, Symbol):
2542*10465441SEvalZero                    self._parse_error("only symbols can imply")
2543*10465441SEvalZero
2544*10465441SEvalZero                node.implies.append((self._expect_nonconst_sym(),
2545*10465441SEvalZero                                     self._parse_cond()))
2546*10465441SEvalZero
2547*10465441SEvalZero            elif t0 is _T_DEFAULT:
2548*10465441SEvalZero                node.defaults.append((self._parse_expr(False),
2549*10465441SEvalZero                                      self._parse_cond()))
2550*10465441SEvalZero
2551*10465441SEvalZero            elif t0 in (_T_DEF_BOOL, _T_DEF_TRISTATE, _T_DEF_INT, _T_DEF_HEX,
2552*10465441SEvalZero                        _T_DEF_STRING):
2553*10465441SEvalZero                self._set_type(node, _TOKEN_TO_TYPE[t0])
2554*10465441SEvalZero                node.defaults.append((self._parse_expr(False),
2555*10465441SEvalZero                                      self._parse_cond()))
2556*10465441SEvalZero
2557*10465441SEvalZero            elif t0 is _T_PROMPT:
2558*10465441SEvalZero                self._parse_prompt(node)
2559*10465441SEvalZero
2560*10465441SEvalZero            elif t0 is _T_RANGE:
2561*10465441SEvalZero                node.ranges.append((self._expect_sym(),
2562*10465441SEvalZero                                    self._expect_sym(),
2563*10465441SEvalZero                                    self._parse_cond()))
2564*10465441SEvalZero
2565*10465441SEvalZero            elif t0 is _T_OPTION:
2566*10465441SEvalZero                if self._check_token(_T_ENV):
2567*10465441SEvalZero                    if not self._check_token(_T_EQUAL):
2568*10465441SEvalZero                        self._parse_error('expected "=" after "env"')
2569*10465441SEvalZero
2570*10465441SEvalZero                    env_var = self._expect_str_and_eol()
2571*10465441SEvalZero                    node.item.env_var = env_var
2572*10465441SEvalZero
2573*10465441SEvalZero                    if env_var in os.environ:
2574*10465441SEvalZero                        node.defaults.append(
2575*10465441SEvalZero                            (self._lookup_const_sym(os.environ[env_var]),
2576*10465441SEvalZero                             self.y))
2577*10465441SEvalZero                    else:
2578*10465441SEvalZero                        self._warn("{1} has 'option env=\"{0}\"', "
2579*10465441SEvalZero                                   "but the environment variable {0} is not "
2580*10465441SEvalZero                                   "set".format(node.item.name, env_var),
2581*10465441SEvalZero                                   self._filename, self._linenr)
2582*10465441SEvalZero
2583*10465441SEvalZero                    if env_var != node.item.name:
2584*10465441SEvalZero                        self._warn("Kconfiglib expands environment variables "
2585*10465441SEvalZero                                   "in strings directly, meaning you do not "
2586*10465441SEvalZero                                   "need 'option env=...' \"bounce\" symbols. "
2587*10465441SEvalZero                                   "For compatibility with the C tools, "
2588*10465441SEvalZero                                   "rename {} to {} (so that the symbol name "
2589*10465441SEvalZero                                   "matches the environment variable name)."
2590*10465441SEvalZero                                   .format(node.item.name, env_var),
2591*10465441SEvalZero                                   self._filename, self._linenr)
2592*10465441SEvalZero
2593*10465441SEvalZero                elif self._check_token(_T_DEFCONFIG_LIST):
2594*10465441SEvalZero                    if not self.defconfig_list:
2595*10465441SEvalZero                        self.defconfig_list = node.item
2596*10465441SEvalZero                    else:
2597*10465441SEvalZero                        self._warn("'option defconfig_list' set on multiple "
2598*10465441SEvalZero                                   "symbols ({0} and {1}). Only {0} will be "
2599*10465441SEvalZero                                   "used.".format(self.defconfig_list.name,
2600*10465441SEvalZero                                                  node.item.name),
2601*10465441SEvalZero                                   self._filename, self._linenr)
2602*10465441SEvalZero
2603*10465441SEvalZero                elif self._check_token(_T_MODULES):
2604*10465441SEvalZero                    # To reduce warning spam, only warn if 'option modules' is
2605*10465441SEvalZero                    # set on some symbol that isn't MODULES, which should be
2606*10465441SEvalZero                    # safe. I haven't run into any projects that make use
2607*10465441SEvalZero                    # modules besides the kernel yet, and there it's likely to
2608*10465441SEvalZero                    # keep being called "MODULES".
2609*10465441SEvalZero                    if node.item is not self.modules:
2610*10465441SEvalZero                        self._warn("the 'modules' option is not supported. "
2611*10465441SEvalZero                                   "Let me know if this is a problem for you, "
2612*10465441SEvalZero                                   "as it wouldn't be that hard to implement. "
2613*10465441SEvalZero                                   "Note that modules are supported -- "
2614*10465441SEvalZero                                   "Kconfiglib just assumes the symbol name "
2615*10465441SEvalZero                                   "MODULES, like older versions of the C "
2616*10465441SEvalZero                                   "implementation did when 'option modules' "
2617*10465441SEvalZero                                   "wasn't used.",
2618*10465441SEvalZero                                   self._filename, self._linenr)
2619*10465441SEvalZero
2620*10465441SEvalZero                elif self._check_token(_T_ALLNOCONFIG_Y):
2621*10465441SEvalZero                    if not isinstance(node.item, Symbol):
2622*10465441SEvalZero                        self._parse_error("the 'allnoconfig_y' option is only "
2623*10465441SEvalZero                                          "valid for symbols")
2624*10465441SEvalZero
2625*10465441SEvalZero                    node.item.is_allnoconfig_y = True
2626*10465441SEvalZero
2627*10465441SEvalZero                else:
2628*10465441SEvalZero                    self._parse_error("unrecognized option")
2629*10465441SEvalZero
2630*10465441SEvalZero            elif t0 is _T_VISIBLE:
2631*10465441SEvalZero                if not self._check_token(_T_IF):
2632*10465441SEvalZero                    self._parse_error('expected "if" after "visible"')
2633*10465441SEvalZero
2634*10465441SEvalZero                node.visibility = self._make_and(node.visibility,
2635*10465441SEvalZero                                                 self._expect_expr_and_eol())
2636*10465441SEvalZero
2637*10465441SEvalZero            elif t0 is _T_OPTIONAL:
2638*10465441SEvalZero                if not isinstance(node.item, Choice):
2639*10465441SEvalZero                    self._parse_error('"optional" is only valid for choices')
2640*10465441SEvalZero
2641*10465441SEvalZero                node.item.is_optional = True
2642*10465441SEvalZero
2643*10465441SEvalZero            else:
2644*10465441SEvalZero                # Reuse the tokens for the non-property line later
2645*10465441SEvalZero                self._has_tokens = True
2646*10465441SEvalZero                self._tokens_i = -1
2647*10465441SEvalZero                return
2648*10465441SEvalZero
2649*10465441SEvalZero    def _set_type(self, node, new_type):
2650*10465441SEvalZero        if node.item.orig_type not in (UNKNOWN, new_type):
2651*10465441SEvalZero            self._warn("{} defined with multiple types, {} will be used"
2652*10465441SEvalZero                       .format(_name_and_loc(node.item),
2653*10465441SEvalZero                               TYPE_TO_STR[new_type]))
2654*10465441SEvalZero
2655*10465441SEvalZero        node.item.orig_type = new_type
2656*10465441SEvalZero
2657*10465441SEvalZero    def _parse_prompt(self, node):
2658*10465441SEvalZero        # 'prompt' properties override each other within a single definition of
2659*10465441SEvalZero        # a symbol, but additional prompts can be added by defining the symbol
2660*10465441SEvalZero        # multiple times
2661*10465441SEvalZero        if node.prompt:
2662*10465441SEvalZero            self._warn(_name_and_loc(node.item) +
2663*10465441SEvalZero                       " defined with multiple prompts in single location")
2664*10465441SEvalZero
2665*10465441SEvalZero        prompt = self._expect_str()
2666*10465441SEvalZero        if prompt != prompt.strip():
2667*10465441SEvalZero            self._warn(_name_and_loc(node.item) +
2668*10465441SEvalZero                       " has leading or trailing whitespace in its prompt")
2669*10465441SEvalZero
2670*10465441SEvalZero            # This avoid issues for e.g. reStructuredText documentation, where
2671*10465441SEvalZero            # '*prompt *' is invalid
2672*10465441SEvalZero            prompt = prompt.strip()
2673*10465441SEvalZero
2674*10465441SEvalZero        node.prompt = (prompt, self._parse_cond())
2675*10465441SEvalZero
2676*10465441SEvalZero    def _parse_help(self, node):
2677*10465441SEvalZero        # Find first non-blank (not all-space) line and get its indentation
2678*10465441SEvalZero
2679*10465441SEvalZero        if node.help is not None:
2680*10465441SEvalZero            self._warn(_name_and_loc(node.item) +
2681*10465441SEvalZero                       " defined with more than one help text -- only the "
2682*10465441SEvalZero                       "last one will be used")
2683*10465441SEvalZero
2684*10465441SEvalZero        # Small optimization. This code is pretty hot.
2685*10465441SEvalZero        readline = self._file.readline
2686*10465441SEvalZero
2687*10465441SEvalZero        while 1:
2688*10465441SEvalZero            line = readline()
2689*10465441SEvalZero            self._linenr += 1
2690*10465441SEvalZero            if not line or not line.isspace():
2691*10465441SEvalZero                break
2692*10465441SEvalZero
2693*10465441SEvalZero        if not line:
2694*10465441SEvalZero            self._warn(_name_and_loc(node.item) +
2695*10465441SEvalZero                       " has 'help' but empty help text")
2696*10465441SEvalZero
2697*10465441SEvalZero            node.help = ""
2698*10465441SEvalZero            return
2699*10465441SEvalZero
2700*10465441SEvalZero        indent = _indentation(line)
2701*10465441SEvalZero        if indent == 0:
2702*10465441SEvalZero            # If the first non-empty lines has zero indent, there is no help
2703*10465441SEvalZero            # text
2704*10465441SEvalZero            self._warn(_name_and_loc(node.item) +
2705*10465441SEvalZero                       " has 'help' but empty help text")
2706*10465441SEvalZero
2707*10465441SEvalZero            node.help = ""
2708*10465441SEvalZero            self._saved_line = line  # "Unget" the line
2709*10465441SEvalZero            return
2710*10465441SEvalZero
2711*10465441SEvalZero        # The help text goes on till the first non-empty line with less indent
2712*10465441SEvalZero        # than the first line
2713*10465441SEvalZero
2714*10465441SEvalZero        help_lines = []
2715*10465441SEvalZero        # Small optimizations
2716*10465441SEvalZero        add_help_line = help_lines.append
2717*10465441SEvalZero        indentation = _indentation
2718*10465441SEvalZero
2719*10465441SEvalZero        while line and (line.isspace() or indentation(line) >= indent):
2720*10465441SEvalZero            # De-indent 'line' by 'indent' spaces and rstrip() it to remove any
2721*10465441SEvalZero            # newlines (which gets rid of other trailing whitespace too, but
2722*10465441SEvalZero            # that's fine).
2723*10465441SEvalZero            #
2724*10465441SEvalZero            # This prepares help text lines in a speedy way: The [indent:]
2725*10465441SEvalZero            # might already remove trailing newlines for lines shorter than
2726*10465441SEvalZero            # indent (e.g. empty lines). The rstrip() makes it consistent,
2727*10465441SEvalZero            # meaning we can join the lines with "\n" later.
2728*10465441SEvalZero            add_help_line(line.expandtabs()[indent:].rstrip())
2729*10465441SEvalZero
2730*10465441SEvalZero            line = readline()
2731*10465441SEvalZero
2732*10465441SEvalZero        self._linenr += len(help_lines)
2733*10465441SEvalZero
2734*10465441SEvalZero        node.help = "\n".join(help_lines).rstrip() + "\n"
2735*10465441SEvalZero        self._saved_line = line  # "Unget" the line
2736*10465441SEvalZero
2737*10465441SEvalZero    def _parse_expr(self, transform_m):
2738*10465441SEvalZero        # Parses an expression from the tokens in Kconfig._tokens using a
2739*10465441SEvalZero        # simple top-down approach. See the module docstring for the expression
2740*10465441SEvalZero        # format.
2741*10465441SEvalZero        #
2742*10465441SEvalZero        # transform_m:
2743*10465441SEvalZero        #   True if m should be rewritten to m && MODULES. See the
2744*10465441SEvalZero        #   Kconfig.eval_string() documentation.
2745*10465441SEvalZero
2746*10465441SEvalZero        # Grammar:
2747*10465441SEvalZero        #
2748*10465441SEvalZero        #   expr:     and_expr ['||' expr]
2749*10465441SEvalZero        #   and_expr: factor ['&&' and_expr]
2750*10465441SEvalZero        #   factor:   <symbol> ['='/'!='/'<'/... <symbol>]
2751*10465441SEvalZero        #             '!' factor
2752*10465441SEvalZero        #             '(' expr ')'
2753*10465441SEvalZero        #
2754*10465441SEvalZero        # It helps to think of the 'expr: and_expr' case as a single-operand OR
2755*10465441SEvalZero        # (no ||), and of the 'and_expr: factor' case as a single-operand AND
2756*10465441SEvalZero        # (no &&). Parsing code is always a bit tricky.
2757*10465441SEvalZero
2758*10465441SEvalZero        # Mind dump: parse_factor() and two nested loops for OR and AND would
2759*10465441SEvalZero        # work as well. The straightforward implementation there gives a
2760*10465441SEvalZero        # (op, (op, (op, A, B), C), D) parse for A op B op C op D. Representing
2761*10465441SEvalZero        # expressions as (op, [list of operands]) instead goes nicely with that
2762*10465441SEvalZero        # version, but is wasteful for short expressions and complicates
2763*10465441SEvalZero        # expression evaluation and other code that works on expressions (more
2764*10465441SEvalZero        # complicated code likely offsets any performance gain from less
2765*10465441SEvalZero        # recursion too). If we also try to optimize the list representation by
2766*10465441SEvalZero        # merging lists when possible (e.g. when ANDing two AND expressions),
2767*10465441SEvalZero        # we end up allocating a ton of lists instead of reusing expressions,
2768*10465441SEvalZero        # which is bad.
2769*10465441SEvalZero
2770*10465441SEvalZero        and_expr = self._parse_and_expr(transform_m)
2771*10465441SEvalZero
2772*10465441SEvalZero        # Return 'and_expr' directly if we have a "single-operand" OR.
2773*10465441SEvalZero        # Otherwise, parse the expression on the right and make an OR node.
2774*10465441SEvalZero        # This turns A || B || C || D into (OR, A, (OR, B, (OR, C, D))).
2775*10465441SEvalZero        return and_expr \
2776*10465441SEvalZero               if not self._check_token(_T_OR) else \
2777*10465441SEvalZero               (OR, and_expr, self._parse_expr(transform_m))
2778*10465441SEvalZero
2779*10465441SEvalZero    def _parse_and_expr(self, transform_m):
2780*10465441SEvalZero        factor = self._parse_factor(transform_m)
2781*10465441SEvalZero
2782*10465441SEvalZero        # Return 'factor' directly if we have a "single-operand" AND.
2783*10465441SEvalZero        # Otherwise, parse the right operand and make an AND node. This turns
2784*10465441SEvalZero        # A && B && C && D into (AND, A, (AND, B, (AND, C, D))).
2785*10465441SEvalZero        return factor \
2786*10465441SEvalZero               if not self._check_token(_T_AND) else \
2787*10465441SEvalZero               (AND, factor, self._parse_and_expr(transform_m))
2788*10465441SEvalZero
2789*10465441SEvalZero    def _parse_factor(self, transform_m):
2790*10465441SEvalZero        token = self._next_token()
2791*10465441SEvalZero
2792*10465441SEvalZero        if isinstance(token, Symbol):
2793*10465441SEvalZero            # Plain symbol or relation
2794*10465441SEvalZero
2795*10465441SEvalZero            next_token = self._peek_token()
2796*10465441SEvalZero            if next_token not in _RELATIONS:
2797*10465441SEvalZero                # Plain symbol
2798*10465441SEvalZero
2799*10465441SEvalZero                # For conditional expressions ('depends on <expr>',
2800*10465441SEvalZero                # '... if <expr>', etc.), m is rewritten to m && MODULES.
2801*10465441SEvalZero                if transform_m and token is self.m:
2802*10465441SEvalZero                    return (AND, self.m, self.modules)
2803*10465441SEvalZero
2804*10465441SEvalZero                return token
2805*10465441SEvalZero
2806*10465441SEvalZero            # Relation
2807*10465441SEvalZero            #
2808*10465441SEvalZero            # _T_EQUAL, _T_UNEQUAL, etc., deliberately have the same values as
2809*10465441SEvalZero            # EQUAL, UNEQUAL, etc., so we can just use the token directly
2810*10465441SEvalZero            return (self._next_token(), token, self._expect_sym())
2811*10465441SEvalZero
2812*10465441SEvalZero        if token is _T_NOT:
2813*10465441SEvalZero            # token == _T_NOT == NOT
2814*10465441SEvalZero            return (token, self._parse_factor(transform_m))
2815*10465441SEvalZero
2816*10465441SEvalZero        if token is _T_OPEN_PAREN:
2817*10465441SEvalZero            expr_parse = self._parse_expr(transform_m)
2818*10465441SEvalZero            if self._check_token(_T_CLOSE_PAREN):
2819*10465441SEvalZero                return expr_parse
2820*10465441SEvalZero
2821*10465441SEvalZero        self._parse_error("malformed expression")
2822*10465441SEvalZero
2823*10465441SEvalZero    #
2824*10465441SEvalZero    # Caching and invalidation
2825*10465441SEvalZero    #
2826*10465441SEvalZero
2827*10465441SEvalZero    def _build_dep(self):
2828*10465441SEvalZero        # Populates the Symbol/Choice._dependents sets, which contain all other
2829*10465441SEvalZero        # items (symbols and choices) that immediately depend on the item in
2830*10465441SEvalZero        # the sense that changing the value of the item might affect the value
2831*10465441SEvalZero        # of the dependent items. This is used for caching/invalidation.
2832*10465441SEvalZero        #
2833*10465441SEvalZero        # The calculated sets might be larger than necessary as we don't do any
2834*10465441SEvalZero        # complex analysis of the expressions.
2835*10465441SEvalZero
2836*10465441SEvalZero        # Only calculate _dependents for defined symbols. Constant and
2837*10465441SEvalZero        # undefined symbols could theoretically be selected/implied, but it
2838*10465441SEvalZero        # wouldn't change their value, so it's not a true dependency.
2839*10465441SEvalZero        for sym in self.unique_defined_syms:
2840*10465441SEvalZero            # Symbols depend on the following:
2841*10465441SEvalZero
2842*10465441SEvalZero            # The prompt conditions
2843*10465441SEvalZero            for node in sym.nodes:
2844*10465441SEvalZero                if node.prompt:
2845*10465441SEvalZero                    _make_depend_on(sym, node.prompt[1])
2846*10465441SEvalZero
2847*10465441SEvalZero            # The default values and their conditions
2848*10465441SEvalZero            for value, cond in sym.defaults:
2849*10465441SEvalZero                _make_depend_on(sym, value)
2850*10465441SEvalZero                _make_depend_on(sym, cond)
2851*10465441SEvalZero
2852*10465441SEvalZero            # The reverse and weak reverse dependencies
2853*10465441SEvalZero            _make_depend_on(sym, sym.rev_dep)
2854*10465441SEvalZero            _make_depend_on(sym, sym.weak_rev_dep)
2855*10465441SEvalZero
2856*10465441SEvalZero            # The ranges along with their conditions
2857*10465441SEvalZero            for low, high, cond in sym.ranges:
2858*10465441SEvalZero                _make_depend_on(sym, low)
2859*10465441SEvalZero                _make_depend_on(sym, high)
2860*10465441SEvalZero                _make_depend_on(sym, cond)
2861*10465441SEvalZero
2862*10465441SEvalZero            # The direct dependencies. This is usually redundant, as the direct
2863*10465441SEvalZero            # dependencies get propagated to properties, but it's needed to get
2864*10465441SEvalZero            # invalidation solid for 'imply', which only checks the direct
2865*10465441SEvalZero            # dependencies (even if there are no properties to propagate it
2866*10465441SEvalZero            # to).
2867*10465441SEvalZero            _make_depend_on(sym, sym.direct_dep)
2868*10465441SEvalZero
2869*10465441SEvalZero            # In addition to the above, choice symbols depend on the choice
2870*10465441SEvalZero            # they're in, but that's handled automatically since the Choice is
2871*10465441SEvalZero            # propagated to the conditions of the properties before
2872*10465441SEvalZero            # _build_dep() runs.
2873*10465441SEvalZero
2874*10465441SEvalZero        for choice in self.unique_choices:
2875*10465441SEvalZero            # Choices depend on the following:
2876*10465441SEvalZero
2877*10465441SEvalZero            # The prompt conditions
2878*10465441SEvalZero            for node in choice.nodes:
2879*10465441SEvalZero                if node.prompt:
2880*10465441SEvalZero                    _make_depend_on(choice, node.prompt[1])
2881*10465441SEvalZero
2882*10465441SEvalZero            # The default symbol conditions
2883*10465441SEvalZero            for _, cond in choice.defaults:
2884*10465441SEvalZero                _make_depend_on(choice, cond)
2885*10465441SEvalZero
2886*10465441SEvalZero    def _add_choice_deps(self):
2887*10465441SEvalZero        # Choices also depend on the choice symbols themselves, because the
2888*10465441SEvalZero        # y-mode selection of the choice might change if a choice symbol's
2889*10465441SEvalZero        # visibility changes.
2890*10465441SEvalZero        #
2891*10465441SEvalZero        # We add these dependencies separately after dependency loop detection.
2892*10465441SEvalZero        # The invalidation algorithm can handle the resulting
2893*10465441SEvalZero        # <choice symbol> <-> <choice> dependency loops, but they make loop
2894*10465441SEvalZero        # detection awkward.
2895*10465441SEvalZero
2896*10465441SEvalZero        for choice in self.unique_choices:
2897*10465441SEvalZero            # The choice symbols themselves, because the y mode selection might
2898*10465441SEvalZero            # change if a choice symbol's visibility changes
2899*10465441SEvalZero            for sym in choice.syms:
2900*10465441SEvalZero                sym._dependents.add(choice)
2901*10465441SEvalZero
2902*10465441SEvalZero    def _invalidate_all(self):
2903*10465441SEvalZero        # Undefined symbols never change value and don't need to be
2904*10465441SEvalZero        # invalidated, so we can just iterate over defined symbols.
2905*10465441SEvalZero        # Invalidating constant symbols would break things horribly.
2906*10465441SEvalZero        for sym in self.unique_defined_syms:
2907*10465441SEvalZero            sym._invalidate()
2908*10465441SEvalZero
2909*10465441SEvalZero        for choice in self.unique_choices:
2910*10465441SEvalZero            choice._invalidate()
2911*10465441SEvalZero
2912*10465441SEvalZero
2913*10465441SEvalZero    #
2914*10465441SEvalZero    # Post-parsing menu tree processing, including dependency propagation and
2915*10465441SEvalZero    # implicit submenu creation
2916*10465441SEvalZero    #
2917*10465441SEvalZero
2918*10465441SEvalZero    def _finalize_tree(self, node, visible_if):
2919*10465441SEvalZero        # Propagates properties and dependencies, creates implicit menus (see
2920*10465441SEvalZero        # kconfig-language.txt), removes 'if' nodes, and finalizes choices.
2921*10465441SEvalZero        # This pretty closely mirrors menu_finalize() from the C
2922*10465441SEvalZero        # implementation, with some minor tweaks (MenuNode holds lists of
2923*10465441SEvalZero        # properties instead of each property having a MenuNode pointer, for
2924*10465441SEvalZero        # example).
2925*10465441SEvalZero        #
2926*10465441SEvalZero        # node:
2927*10465441SEvalZero        #   The current "parent" menu node, from which we propagate
2928*10465441SEvalZero        #   dependencies
2929*10465441SEvalZero        #
2930*10465441SEvalZero        # visible_if:
2931*10465441SEvalZero        #   Dependencies from 'visible if' on parent menus. These are added to
2932*10465441SEvalZero        #   the prompts of symbols and choices.
2933*10465441SEvalZero
2934*10465441SEvalZero        if node.list:
2935*10465441SEvalZero            # The menu node is a choice, menu, or if. Finalize each child in
2936*10465441SEvalZero            # it.
2937*10465441SEvalZero
2938*10465441SEvalZero            if node.item is MENU:
2939*10465441SEvalZero                visible_if = self._make_and(visible_if, node.visibility)
2940*10465441SEvalZero
2941*10465441SEvalZero            # Propagate the menu node's dependencies to each child menu node.
2942*10465441SEvalZero            #
2943*10465441SEvalZero            # The recursive _finalize_tree() calls assume that the current
2944*10465441SEvalZero            # "level" in the tree has already had dependencies propagated. This
2945*10465441SEvalZero            # makes e.g. implicit submenu creation easier, because it needs to
2946*10465441SEvalZero            # look ahead.
2947*10465441SEvalZero            self._propagate_deps(node, visible_if)
2948*10465441SEvalZero
2949*10465441SEvalZero            # Finalize the children
2950*10465441SEvalZero            cur = node.list
2951*10465441SEvalZero            while cur:
2952*10465441SEvalZero                self._finalize_tree(cur, visible_if)
2953*10465441SEvalZero                cur = cur.next
2954*10465441SEvalZero
2955*10465441SEvalZero        elif isinstance(node.item, Symbol):
2956*10465441SEvalZero            # Add the node's non-node-specific properties (defaults, ranges,
2957*10465441SEvalZero            # etc.) to the Symbol
2958*10465441SEvalZero            self._add_props_to_sc(node)
2959*10465441SEvalZero
2960*10465441SEvalZero            # See if we can create an implicit menu rooted at the Symbol and
2961*10465441SEvalZero            # finalize each child menu node in that menu if so, like for the
2962*10465441SEvalZero            # choice/menu/if case above
2963*10465441SEvalZero            cur = node
2964*10465441SEvalZero            while cur.next and _auto_menu_dep(node, cur.next):
2965*10465441SEvalZero                # This also makes implicit submenu creation work recursively,
2966*10465441SEvalZero                # with implicit menus inside implicit menus
2967*10465441SEvalZero                self._finalize_tree(cur.next, visible_if)
2968*10465441SEvalZero                cur = cur.next
2969*10465441SEvalZero                cur.parent = node
2970*10465441SEvalZero
2971*10465441SEvalZero            if cur is not node:
2972*10465441SEvalZero                # Found symbols that should go in an implicit submenu. Tilt
2973*10465441SEvalZero                # them up above us.
2974*10465441SEvalZero                node.list = node.next
2975*10465441SEvalZero                node.next = cur.next
2976*10465441SEvalZero                cur.next = None
2977*10465441SEvalZero
2978*10465441SEvalZero
2979*10465441SEvalZero        if node.list:
2980*10465441SEvalZero            # We have a parent node with individually finalized child nodes. Do
2981*10465441SEvalZero            # final steps to finalize this "level" in the menu tree.
2982*10465441SEvalZero            _flatten(node.list)
2983*10465441SEvalZero            _remove_ifs(node)
2984*10465441SEvalZero
2985*10465441SEvalZero        # Empty choices (node.list None) are possible, so this needs to go
2986*10465441SEvalZero        # outside
2987*10465441SEvalZero        if isinstance(node.item, Choice):
2988*10465441SEvalZero            # Add the node's non-node-specific properties to the choice
2989*10465441SEvalZero            self._add_props_to_sc(node)
2990*10465441SEvalZero            _finalize_choice(node)
2991*10465441SEvalZero
2992*10465441SEvalZero    def _propagate_deps(self, node, visible_if):
2993*10465441SEvalZero        # Propagates 'node's dependencies to its child menu nodes
2994*10465441SEvalZero
2995*10465441SEvalZero        # If the parent node holds a Choice, we use the Choice itself as the
2996*10465441SEvalZero        # parent dependency. This makes sense as the value (mode) of the choice
2997*10465441SEvalZero        # limits the visibility of the contained choice symbols. The C
2998*10465441SEvalZero        # implementation works the same way.
2999*10465441SEvalZero        #
3000*10465441SEvalZero        # Due to the similar interface, Choice works as a drop-in replacement
3001*10465441SEvalZero        # for Symbol here.
3002*10465441SEvalZero        basedep = node.item if isinstance(node.item, Choice) else node.dep
3003*10465441SEvalZero
3004*10465441SEvalZero        cur = node.list
3005*10465441SEvalZero        while cur:
3006*10465441SEvalZero            cur.dep = dep = self._make_and(cur.dep, basedep)
3007*10465441SEvalZero
3008*10465441SEvalZero            # Propagate dependencies to prompt
3009*10465441SEvalZero            if cur.prompt:
3010*10465441SEvalZero                cur.prompt = (cur.prompt[0],
3011*10465441SEvalZero                              self._make_and(cur.prompt[1], dep))
3012*10465441SEvalZero
3013*10465441SEvalZero            if isinstance(cur.item, (Symbol, Choice)):
3014*10465441SEvalZero                sc = cur.item
3015*10465441SEvalZero
3016*10465441SEvalZero                # Propagate 'visible if' dependencies to the prompt
3017*10465441SEvalZero                if cur.prompt:
3018*10465441SEvalZero                    cur.prompt = (cur.prompt[0],
3019*10465441SEvalZero                                  self._make_and(cur.prompt[1], visible_if))
3020*10465441SEvalZero
3021*10465441SEvalZero                # Propagate dependencies to defaults
3022*10465441SEvalZero                if cur.defaults:
3023*10465441SEvalZero                    cur.defaults = [(default, self._make_and(cond, dep))
3024*10465441SEvalZero                                    for default, cond in cur.defaults]
3025*10465441SEvalZero
3026*10465441SEvalZero                # Propagate dependencies to ranges
3027*10465441SEvalZero                if cur.ranges:
3028*10465441SEvalZero                    cur.ranges = [(low, high, self._make_and(cond, dep))
3029*10465441SEvalZero                                  for low, high, cond in cur.ranges]
3030*10465441SEvalZero
3031*10465441SEvalZero                # Propagate dependencies to selects
3032*10465441SEvalZero                if cur.selects:
3033*10465441SEvalZero                    cur.selects = [(target, self._make_and(cond, dep))
3034*10465441SEvalZero                                   for target, cond in cur.selects]
3035*10465441SEvalZero
3036*10465441SEvalZero                # Propagate dependencies to implies
3037*10465441SEvalZero                if cur.implies:
3038*10465441SEvalZero                    cur.implies = [(target, self._make_and(cond, dep))
3039*10465441SEvalZero                                   for target, cond in cur.implies]
3040*10465441SEvalZero
3041*10465441SEvalZero
3042*10465441SEvalZero            cur = cur.next
3043*10465441SEvalZero
3044*10465441SEvalZero    def _add_props_to_sc(self, node):
3045*10465441SEvalZero        # Copies properties from the menu node 'node' up to its contained
3046*10465441SEvalZero        # symbol or choice.
3047*10465441SEvalZero        #
3048*10465441SEvalZero        # This can't be rolled into _propagate_deps(), because that function
3049*10465441SEvalZero        # traverses the menu tree roughly breadth-first order, meaning
3050*10465441SEvalZero        # properties on symbols and choices defined in multiple locations could
3051*10465441SEvalZero        # end up in the wrong order.
3052*10465441SEvalZero
3053*10465441SEvalZero        # Symbol or choice
3054*10465441SEvalZero        sc = node.item
3055*10465441SEvalZero
3056*10465441SEvalZero        # See the Symbol class docstring
3057*10465441SEvalZero        sc.direct_dep = self._make_or(sc.direct_dep, node.dep)
3058*10465441SEvalZero
3059*10465441SEvalZero        sc.defaults += node.defaults
3060*10465441SEvalZero
3061*10465441SEvalZero        # The properties below aren't available on choices
3062*10465441SEvalZero
3063*10465441SEvalZero        if node.ranges:
3064*10465441SEvalZero            sc.ranges += node.ranges
3065*10465441SEvalZero
3066*10465441SEvalZero        if node.selects:
3067*10465441SEvalZero            sc.selects += node.selects
3068*10465441SEvalZero
3069*10465441SEvalZero            # Modify the reverse dependencies of the selected symbol
3070*10465441SEvalZero            for target, cond in node.selects:
3071*10465441SEvalZero                target.rev_dep = self._make_or(
3072*10465441SEvalZero                    target.rev_dep,
3073*10465441SEvalZero                    self._make_and(sc, cond))
3074*10465441SEvalZero
3075*10465441SEvalZero        if node.implies:
3076*10465441SEvalZero            sc.implies += node.implies
3077*10465441SEvalZero
3078*10465441SEvalZero            # Modify the weak reverse dependencies of the implied
3079*10465441SEvalZero            # symbol
3080*10465441SEvalZero            for target, cond in node.implies:
3081*10465441SEvalZero                target.weak_rev_dep = self._make_or(
3082*10465441SEvalZero                    target.weak_rev_dep,
3083*10465441SEvalZero                    self._make_and(sc, cond))
3084*10465441SEvalZero
3085*10465441SEvalZero
3086*10465441SEvalZero    #
3087*10465441SEvalZero    # Misc.
3088*10465441SEvalZero    #
3089*10465441SEvalZero
3090*10465441SEvalZero    def _parse_error(self, msg):
3091*10465441SEvalZero        if self._filename is None:
3092*10465441SEvalZero            loc = ""
3093*10465441SEvalZero        else:
3094*10465441SEvalZero            loc = "{}:{}: ".format(self._filename, self._linenr)
3095*10465441SEvalZero
3096*10465441SEvalZero        raise KconfigError(
3097*10465441SEvalZero            "{}couldn't parse '{}': {}".format(loc, self._line.rstrip(), msg))
3098*10465441SEvalZero
3099*10465441SEvalZero    def _open(self, filename, mode):
3100*10465441SEvalZero        # open() wrapper:
3101*10465441SEvalZero        #
3102*10465441SEvalZero        # - Enable universal newlines mode on Python 2 to ease
3103*10465441SEvalZero        #   interoperability between Linux and Windows. It's already the
3104*10465441SEvalZero        #   default on Python 3.
3105*10465441SEvalZero        #
3106*10465441SEvalZero        #   The "U" flag would currently work for both Python 2 and 3, but it's
3107*10465441SEvalZero        #   deprecated on Python 3, so play it future-safe.
3108*10465441SEvalZero        #
3109*10465441SEvalZero        #   A simpler solution would be to use io.open(), which defaults to
3110*10465441SEvalZero        #   universal newlines on both Python 2 and 3 (and is an alias for
3111*10465441SEvalZero        #   open() on Python 3), but it's appreciably slower on Python 2:
3112*10465441SEvalZero        #
3113*10465441SEvalZero        #     Parsing x86 Kconfigs on Python 2
3114*10465441SEvalZero        #
3115*10465441SEvalZero        #     with open(..., "rU"):
3116*10465441SEvalZero        #
3117*10465441SEvalZero        #       real  0m0.930s
3118*10465441SEvalZero        #       user  0m0.905s
3119*10465441SEvalZero        #       sys   0m0.025s
3120*10465441SEvalZero        #
3121*10465441SEvalZero        #     with io.open():
3122*10465441SEvalZero        #
3123*10465441SEvalZero        #       real  0m1.069s
3124*10465441SEvalZero        #       user  0m1.040s
3125*10465441SEvalZero        #       sys   0m0.029s
3126*10465441SEvalZero        #
3127*10465441SEvalZero        #   There's no appreciable performance difference between "r" and
3128*10465441SEvalZero        #   "rU" for parsing performance on Python 2.
3129*10465441SEvalZero        #
3130*10465441SEvalZero        # - For Python 3, force the encoding. Forcing the encoding on Python 2
3131*10465441SEvalZero        #   turns strings into Unicode strings, which gets messy. Python 2
3132*10465441SEvalZero        #   doesn't decode regular strings anyway.
3133*10465441SEvalZero        return open(filename, "rU" if mode == "r" else mode) if _IS_PY2 else \
3134*10465441SEvalZero               open(filename, mode, encoding=self._encoding)
3135*10465441SEvalZero
3136*10465441SEvalZero    def _check_undef_syms(self):
3137*10465441SEvalZero        # Prints warnings for all references to undefined symbols within the
3138*10465441SEvalZero        # Kconfig files
3139*10465441SEvalZero
3140*10465441SEvalZero        for sym in (self.syms.viewvalues if _IS_PY2 else self.syms.values)():
3141*10465441SEvalZero            # - sym.nodes empty means the symbol is undefined (has no
3142*10465441SEvalZero            #   definition locations)
3143*10465441SEvalZero            #
3144*10465441SEvalZero            # - Due to Kconfig internals, numbers show up as undefined Kconfig
3145*10465441SEvalZero            #   symbols, but shouldn't be flagged
3146*10465441SEvalZero            #
3147*10465441SEvalZero            # - The MODULES symbol always exists
3148*10465441SEvalZero            if not sym.nodes and not _is_num(sym.name) and \
3149*10465441SEvalZero               sym.name != "MODULES":
3150*10465441SEvalZero
3151*10465441SEvalZero                msg = "undefined symbol {}:".format(sym.name)
3152*10465441SEvalZero
3153*10465441SEvalZero                for node in self.node_iter():
3154*10465441SEvalZero                    if sym in node.referenced:
3155*10465441SEvalZero                        msg += "\n\n- Referenced at {}:{}:\n\n{}" \
3156*10465441SEvalZero                               .format(node.filename, node.linenr, node)
3157*10465441SEvalZero
3158*10465441SEvalZero                self._warn(msg)
3159*10465441SEvalZero
3160*10465441SEvalZero    def _warn(self, msg, filename=None, linenr=None):
3161*10465441SEvalZero        # For printing general warnings
3162*10465441SEvalZero
3163*10465441SEvalZero        if self._warnings_enabled:
3164*10465441SEvalZero            msg = "warning: " + msg
3165*10465441SEvalZero            if filename is not None:
3166*10465441SEvalZero                msg = "{}:{}: {}".format(filename, linenr, msg)
3167*10465441SEvalZero
3168*10465441SEvalZero            self.warnings.append(msg)
3169*10465441SEvalZero            if self._warn_to_stderr:
3170*10465441SEvalZero                sys.stderr.write(msg + "\n")
3171*10465441SEvalZero
3172*10465441SEvalZero    def _warn_undef_assign(self, msg, filename=None, linenr=None):
3173*10465441SEvalZero        # See the class documentation
3174*10465441SEvalZero
3175*10465441SEvalZero        if self._warn_for_undef_assign:
3176*10465441SEvalZero            self._warn(msg, filename, linenr)
3177*10465441SEvalZero
3178*10465441SEvalZero    def _warn_undef_assign_load(self, name, val, filename, linenr):
3179*10465441SEvalZero        # Special version for load_config()
3180*10465441SEvalZero
3181*10465441SEvalZero        self._warn_undef_assign(
3182*10465441SEvalZero            'attempt to assign the value "{}" to the undefined symbol {}'
3183*10465441SEvalZero            .format(val, name), filename, linenr)
3184*10465441SEvalZero
3185*10465441SEvalZero    def _warn_redun_assign(self, msg, filename=None, linenr=None):
3186*10465441SEvalZero        # See the class documentation
3187*10465441SEvalZero
3188*10465441SEvalZero        if self._warn_for_redun_assign:
3189*10465441SEvalZero            self._warn(msg, filename, linenr)
3190*10465441SEvalZero
3191*10465441SEvalZero    def _srctree_hint(self):
3192*10465441SEvalZero        # Hint printed when Kconfig files can't be found or .config files can't
3193*10465441SEvalZero        # be opened
3194*10465441SEvalZero
3195*10465441SEvalZero        return ". Perhaps the $srctree environment variable ({}) " \
3196*10465441SEvalZero               "is set incorrectly. Note that the current value of $srctree " \
3197*10465441SEvalZero               "is saved when the Kconfig instance is created (for " \
3198*10465441SEvalZero               "consistency and to cleanly separate instances)." \
3199*10465441SEvalZero               .format("set to '{}'".format(self.srctree) if self.srctree
3200*10465441SEvalZero                           else "unset or blank")
3201*10465441SEvalZero
3202*10465441SEvalZeroclass Symbol(object):
3203*10465441SEvalZero    """
3204*10465441SEvalZero    Represents a configuration symbol:
3205*10465441SEvalZero
3206*10465441SEvalZero      (menu)config FOO
3207*10465441SEvalZero          ...
3208*10465441SEvalZero
3209*10465441SEvalZero    The following attributes are available. They should be viewed as read-only,
3210*10465441SEvalZero    and some are implemented through @property magic (but are still efficient
3211*10465441SEvalZero    to access due to internal caching).
3212*10465441SEvalZero
3213*10465441SEvalZero    Note: Prompts, help texts, and locations are stored in the Symbol's
3214*10465441SEvalZero    MenuNode(s) rather than in the Symbol itself. Check the MenuNode class and
3215*10465441SEvalZero    the Symbol.nodes attribute. This organization matches the C tools.
3216*10465441SEvalZero
3217*10465441SEvalZero    name:
3218*10465441SEvalZero      The name of the symbol, e.g. "FOO" for 'config FOO'.
3219*10465441SEvalZero
3220*10465441SEvalZero    type:
3221*10465441SEvalZero      The type of the symbol. One of BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN.
3222*10465441SEvalZero      UNKNOWN is for undefined symbols, (non-special) constant symbols, and
3223*10465441SEvalZero      symbols defined without a type.
3224*10465441SEvalZero
3225*10465441SEvalZero      When running without modules (MODULES having the value n), TRISTATE
3226*10465441SEvalZero      symbols magically change type to BOOL. This also happens for symbols
3227*10465441SEvalZero      within choices in "y" mode. This matches the C tools, and makes sense for
3228*10465441SEvalZero      menuconfig-like functionality.
3229*10465441SEvalZero
3230*10465441SEvalZero    orig_type:
3231*10465441SEvalZero      The type as given in the Kconfig file, without any magic applied. Used
3232*10465441SEvalZero      when printing the symbol.
3233*10465441SEvalZero
3234*10465441SEvalZero    str_value:
3235*10465441SEvalZero      The value of the symbol as a string. Gives the value for string/int/hex
3236*10465441SEvalZero      symbols. For bool/tristate symbols, gives "n", "m", or "y".
3237*10465441SEvalZero
3238*10465441SEvalZero      This is the symbol value that's used in relational expressions
3239*10465441SEvalZero      (A = B, A != B, etc.)
3240*10465441SEvalZero
3241*10465441SEvalZero      Gotcha: For int/hex symbols, the exact format of the value must often be
3242*10465441SEvalZero      preserved (e.g., when writing a .config file), hence why you can't get it
3243*10465441SEvalZero      directly as an int. Do int(int_sym.str_value) or
3244*10465441SEvalZero      int(hex_sym.str_value, 16) to get the integer value.
3245*10465441SEvalZero
3246*10465441SEvalZero    tri_value:
3247*10465441SEvalZero      The tristate value of the symbol as an integer. One of 0, 1, 2,
3248*10465441SEvalZero      representing n, m, y. Always 0 (n) for non-bool/tristate symbols.
3249*10465441SEvalZero
3250*10465441SEvalZero      This is the symbol value that's used outside of relation expressions
3251*10465441SEvalZero      (A, !A, A && B, A || B).
3252*10465441SEvalZero
3253*10465441SEvalZero    assignable:
3254*10465441SEvalZero      A tuple containing the tristate user values that can currently be
3255*10465441SEvalZero      assigned to the symbol (that would be respected), ordered from lowest (0,
3256*10465441SEvalZero      representing n) to highest (2, representing y). This corresponds to the
3257*10465441SEvalZero      selections available in the menuconfig interface. The set of assignable
3258*10465441SEvalZero      values is calculated from the symbol's visibility and selects/implies.
3259*10465441SEvalZero
3260*10465441SEvalZero      Returns the empty set for non-bool/tristate symbols and for symbols with
3261*10465441SEvalZero      visibility n. The other possible values are (0, 2), (0, 1, 2), (1, 2),
3262*10465441SEvalZero      (1,), and (2,). A (1,) or (2,) result means the symbol is visible but
3263*10465441SEvalZero      "locked" to m or y through a select, perhaps in combination with the
3264*10465441SEvalZero      visibility. menuconfig represents this as -M- and -*-, respectively.
3265*10465441SEvalZero
3266*10465441SEvalZero      For string/hex/int symbols, check if Symbol.visibility is non-0 (non-n)
3267*10465441SEvalZero      instead to determine if the value can be changed.
3268*10465441SEvalZero
3269*10465441SEvalZero      Some handy 'assignable' idioms:
3270*10465441SEvalZero
3271*10465441SEvalZero        # Is 'sym' an assignable (visible) bool/tristate symbol?
3272*10465441SEvalZero        if sym.assignable:
3273*10465441SEvalZero            # What's the highest value it can be assigned? [-1] in Python
3274*10465441SEvalZero            # gives the last element.
3275*10465441SEvalZero            sym_high = sym.assignable[-1]
3276*10465441SEvalZero
3277*10465441SEvalZero            # The lowest?
3278*10465441SEvalZero            sym_low = sym.assignable[0]
3279*10465441SEvalZero
3280*10465441SEvalZero            # Can the symbol be set to at least m?
3281*10465441SEvalZero            if sym.assignable[-1] >= 1:
3282*10465441SEvalZero                ...
3283*10465441SEvalZero
3284*10465441SEvalZero        # Can the symbol be set to m?
3285*10465441SEvalZero        if 1 in sym.assignable:
3286*10465441SEvalZero            ...
3287*10465441SEvalZero
3288*10465441SEvalZero    visibility:
3289*10465441SEvalZero      The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See
3290*10465441SEvalZero      the module documentation for an overview of symbol values and visibility.
3291*10465441SEvalZero
3292*10465441SEvalZero    user_value:
3293*10465441SEvalZero      The user value of the symbol. None if no user value has been assigned
3294*10465441SEvalZero      (via Kconfig.load_config() or Symbol.set_value()).
3295*10465441SEvalZero
3296*10465441SEvalZero      Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other
3297*10465441SEvalZero      symbol types.
3298*10465441SEvalZero
3299*10465441SEvalZero      WARNING: Do not assign directly to this. It will break things. Use
3300*10465441SEvalZero      Symbol.set_value().
3301*10465441SEvalZero
3302*10465441SEvalZero    config_string:
3303*10465441SEvalZero      The .config assignment string that would get written out for the symbol
3304*10465441SEvalZero      by Kconfig.write_config(). Returns the empty string if no .config
3305*10465441SEvalZero      assignment would get written out. In general, visible symbols, symbols
3306*10465441SEvalZero      with (active) defaults, and selected symbols get written out.
3307*10465441SEvalZero
3308*10465441SEvalZero    nodes:
3309*10465441SEvalZero      A list of MenuNodes for this symbol. Will contain a single MenuNode for
3310*10465441SEvalZero      most symbols. Undefined and constant symbols have an empty nodes list.
3311*10465441SEvalZero      Symbols defined in multiple locations get one node for each location.
3312*10465441SEvalZero
3313*10465441SEvalZero    choice:
3314*10465441SEvalZero      Holds the parent Choice for choice symbols, and None for non-choice
3315*10465441SEvalZero      symbols. Doubles as a flag for whether a symbol is a choice symbol.
3316*10465441SEvalZero
3317*10465441SEvalZero    defaults:
3318*10465441SEvalZero      List of (default, cond) tuples for the symbol's 'default' properties. For
3319*10465441SEvalZero      example, 'default A && B if C || D' is represented as
3320*10465441SEvalZero      ((AND, A, B), (OR, C, D)). If no condition was given, 'cond' is
3321*10465441SEvalZero      self.kconfig.y.
3322*10465441SEvalZero
3323*10465441SEvalZero      Note that 'depends on' and parent dependencies are propagated to
3324*10465441SEvalZero      'default' conditions.
3325*10465441SEvalZero
3326*10465441SEvalZero    selects:
3327*10465441SEvalZero      List of (symbol, cond) tuples for the symbol's 'select' properties. For
3328*10465441SEvalZero      example, 'select A if B && C' is represented as (A, (AND, B, C)). If no
3329*10465441SEvalZero      condition was given, 'cond' is self.kconfig.y.
3330*10465441SEvalZero
3331*10465441SEvalZero      Note that 'depends on' and parent dependencies are propagated to 'select'
3332*10465441SEvalZero      conditions.
3333*10465441SEvalZero
3334*10465441SEvalZero    implies:
3335*10465441SEvalZero      Like 'selects', for imply.
3336*10465441SEvalZero
3337*10465441SEvalZero    ranges:
3338*10465441SEvalZero      List of (low, high, cond) tuples for the symbol's 'range' properties. For
3339*10465441SEvalZero      example, 'range 1 2 if A' is represented as (1, 2, A). If there is no
3340*10465441SEvalZero      condition, 'cond' is self.config.y.
3341*10465441SEvalZero
3342*10465441SEvalZero      Note that 'depends on' and parent dependencies are propagated to 'range'
3343*10465441SEvalZero      conditions.
3344*10465441SEvalZero
3345*10465441SEvalZero      Gotcha: 1 and 2 above will be represented as (undefined) Symbols rather
3346*10465441SEvalZero      than plain integers. Undefined symbols get their name as their string
3347*10465441SEvalZero      value, so this works out. The C tools work the same way.
3348*10465441SEvalZero
3349*10465441SEvalZero    rev_dep:
3350*10465441SEvalZero      Reverse dependency expression from other symbols selecting this symbol.
3351*10465441SEvalZero      Multiple selections get ORed together. A condition on a select is ANDed
3352*10465441SEvalZero      with the selecting symbol.
3353*10465441SEvalZero
3354*10465441SEvalZero      For example, if A has 'select FOO' and B has 'select FOO if C', then
3355*10465441SEvalZero      FOO's rev_dep will be (OR, A, (AND, B, C)).
3356*10465441SEvalZero
3357*10465441SEvalZero    weak_rev_dep:
3358*10465441SEvalZero      Like rev_dep, for imply.
3359*10465441SEvalZero
3360*10465441SEvalZero    direct_dep:
3361*10465441SEvalZero      The 'depends on' dependencies. If a symbol is defined in multiple
3362*10465441SEvalZero      locations, the dependencies at each location are ORed together.
3363*10465441SEvalZero
3364*10465441SEvalZero      Internally, this is used to implement 'imply', which only applies if the
3365*10465441SEvalZero      implied symbol has expr_value(self.direct_dep) != 0. 'depends on' and
3366*10465441SEvalZero      parent dependencies are automatically propagated to the conditions of
3367*10465441SEvalZero      properties, so normally it's redundant to check the direct dependencies.
3368*10465441SEvalZero
3369*10465441SEvalZero    referenced:
3370*10465441SEvalZero      A set() with all symbols and choices referenced in the properties and
3371*10465441SEvalZero      property conditions of the symbol.
3372*10465441SEvalZero
3373*10465441SEvalZero      Also includes dependencies inherited from surrounding menus and if's.
3374*10465441SEvalZero      Choices appear in the dependencies of choice symbols.
3375*10465441SEvalZero
3376*10465441SEvalZero    env_var:
3377*10465441SEvalZero      If the Symbol has an 'option env="FOO"' option, this contains the name
3378*10465441SEvalZero      ("FOO") of the environment variable. None for symbols without no
3379*10465441SEvalZero      'option env'.
3380*10465441SEvalZero
3381*10465441SEvalZero      'option env="FOO"' acts like a 'default' property whose value is the
3382*10465441SEvalZero      value of $FOO.
3383*10465441SEvalZero
3384*10465441SEvalZero      Symbols with 'option env' are never written out to .config files, even if
3385*10465441SEvalZero      they are visible. env_var corresponds to a flag called SYMBOL_AUTO in the
3386*10465441SEvalZero      C implementation.
3387*10465441SEvalZero
3388*10465441SEvalZero    is_allnoconfig_y:
3389*10465441SEvalZero      True if the symbol has 'option allnoconfig_y' set on it. This has no
3390*10465441SEvalZero      effect internally (except when printing symbols), but can be checked by
3391*10465441SEvalZero      scripts.
3392*10465441SEvalZero
3393*10465441SEvalZero    is_constant:
3394*10465441SEvalZero      True if the symbol is a constant (quoted) symbol.
3395*10465441SEvalZero
3396*10465441SEvalZero    kconfig:
3397*10465441SEvalZero      The Kconfig instance this symbol is from.
3398*10465441SEvalZero    """
3399*10465441SEvalZero    __slots__ = (
3400*10465441SEvalZero        "_cached_assignable",
3401*10465441SEvalZero        "_cached_str_val",
3402*10465441SEvalZero        "_cached_tri_val",
3403*10465441SEvalZero        "_cached_vis",
3404*10465441SEvalZero        "_dependents",
3405*10465441SEvalZero        "_old_val",
3406*10465441SEvalZero        "_visited",
3407*10465441SEvalZero        "_was_set",
3408*10465441SEvalZero        "_write_to_conf",
3409*10465441SEvalZero        "choice",
3410*10465441SEvalZero        "defaults",
3411*10465441SEvalZero        "direct_dep",
3412*10465441SEvalZero        "env_var",
3413*10465441SEvalZero        "implies",
3414*10465441SEvalZero        "is_allnoconfig_y",
3415*10465441SEvalZero        "is_constant",
3416*10465441SEvalZero        "kconfig",
3417*10465441SEvalZero        "name",
3418*10465441SEvalZero        "nodes",
3419*10465441SEvalZero        "orig_type",
3420*10465441SEvalZero        "ranges",
3421*10465441SEvalZero        "rev_dep",
3422*10465441SEvalZero        "selects",
3423*10465441SEvalZero        "user_value",
3424*10465441SEvalZero        "weak_rev_dep",
3425*10465441SEvalZero    )
3426*10465441SEvalZero
3427*10465441SEvalZero    #
3428*10465441SEvalZero    # Public interface
3429*10465441SEvalZero    #
3430*10465441SEvalZero
3431*10465441SEvalZero    @property
3432*10465441SEvalZero    def type(self):
3433*10465441SEvalZero        """
3434*10465441SEvalZero        See the class documentation.
3435*10465441SEvalZero        """
3436*10465441SEvalZero        if self.orig_type is TRISTATE and \
3437*10465441SEvalZero           ((self.choice and self.choice.tri_value == 2) or
3438*10465441SEvalZero            not self.kconfig.modules.tri_value):
3439*10465441SEvalZero            return BOOL
3440*10465441SEvalZero
3441*10465441SEvalZero        return self.orig_type
3442*10465441SEvalZero
3443*10465441SEvalZero    @property
3444*10465441SEvalZero    def str_value(self):
3445*10465441SEvalZero        """
3446*10465441SEvalZero        See the class documentation.
3447*10465441SEvalZero        """
3448*10465441SEvalZero        if self._cached_str_val is not None:
3449*10465441SEvalZero            return self._cached_str_val
3450*10465441SEvalZero
3451*10465441SEvalZero        if self.orig_type in (BOOL, TRISTATE):
3452*10465441SEvalZero            # Also calculates the visibility, so invalidation safe
3453*10465441SEvalZero            self._cached_str_val = TRI_TO_STR[self.tri_value]
3454*10465441SEvalZero            return self._cached_str_val
3455*10465441SEvalZero
3456*10465441SEvalZero        # As a quirk of Kconfig, undefined symbols get their name as their
3457*10465441SEvalZero        # string value. This is why things like "FOO = bar" work for seeing if
3458*10465441SEvalZero        # FOO has the value "bar".
3459*10465441SEvalZero        if self.orig_type is UNKNOWN:
3460*10465441SEvalZero            self._cached_str_val = self.name
3461*10465441SEvalZero            return self.name
3462*10465441SEvalZero
3463*10465441SEvalZero        val = ""
3464*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
3465*10465441SEvalZero        # function call (property magic)
3466*10465441SEvalZero        vis = self.visibility
3467*10465441SEvalZero
3468*10465441SEvalZero        self._write_to_conf = (vis != 0)
3469*10465441SEvalZero
3470*10465441SEvalZero        if self.orig_type in (INT, HEX):
3471*10465441SEvalZero            # The C implementation checks the user value against the range in a
3472*10465441SEvalZero            # separate code path (post-processing after loading a .config).
3473*10465441SEvalZero            # Checking all values here instead makes more sense for us. It
3474*10465441SEvalZero            # requires that we check for a range first.
3475*10465441SEvalZero
3476*10465441SEvalZero            base = _TYPE_TO_BASE[self.orig_type]
3477*10465441SEvalZero
3478*10465441SEvalZero            # Check if a range is in effect
3479*10465441SEvalZero            for low_expr, high_expr, cond in self.ranges:
3480*10465441SEvalZero                if expr_value(cond):
3481*10465441SEvalZero                    has_active_range = True
3482*10465441SEvalZero
3483*10465441SEvalZero                    # The zeros are from the C implementation running strtoll()
3484*10465441SEvalZero                    # on empty strings
3485*10465441SEvalZero                    low = int(low_expr.str_value, base) if \
3486*10465441SEvalZero                      _is_base_n(low_expr.str_value, base) else 0
3487*10465441SEvalZero                    high = int(high_expr.str_value, base) if \
3488*10465441SEvalZero                      _is_base_n(high_expr.str_value, base) else 0
3489*10465441SEvalZero
3490*10465441SEvalZero                    break
3491*10465441SEvalZero            else:
3492*10465441SEvalZero                has_active_range = False
3493*10465441SEvalZero
3494*10465441SEvalZero            # Defaults are used if the symbol is invisible, lacks a user value,
3495*10465441SEvalZero            # or has an out-of-range user value.
3496*10465441SEvalZero            use_defaults = True
3497*10465441SEvalZero
3498*10465441SEvalZero            if vis and self.user_value:
3499*10465441SEvalZero                user_val = int(self.user_value, base)
3500*10465441SEvalZero                if has_active_range and not low <= user_val <= high:
3501*10465441SEvalZero                    num2str = str if base == 10 else hex
3502*10465441SEvalZero                    self.kconfig._warn(
3503*10465441SEvalZero                        "user value {} on the {} symbol {} ignored due to "
3504*10465441SEvalZero                        "being outside the active range ([{}, {}]) -- falling "
3505*10465441SEvalZero                        "back on defaults"
3506*10465441SEvalZero                        .format(num2str(user_val), TYPE_TO_STR[self.orig_type],
3507*10465441SEvalZero                                _name_and_loc(self),
3508*10465441SEvalZero                                num2str(low), num2str(high)))
3509*10465441SEvalZero                else:
3510*10465441SEvalZero                    # If the user value is well-formed and satisfies range
3511*10465441SEvalZero                    # contraints, it is stored in exactly the same form as
3512*10465441SEvalZero                    # specified in the assignment (with or without "0x", etc.)
3513*10465441SEvalZero                    val = self.user_value
3514*10465441SEvalZero                    use_defaults = False
3515*10465441SEvalZero
3516*10465441SEvalZero            if use_defaults:
3517*10465441SEvalZero                # No user value or invalid user value. Look at defaults.
3518*10465441SEvalZero
3519*10465441SEvalZero                # Used to implement the warning below
3520*10465441SEvalZero                has_default = False
3521*10465441SEvalZero
3522*10465441SEvalZero                for val_sym, cond in self.defaults:
3523*10465441SEvalZero                    if expr_value(cond):
3524*10465441SEvalZero                        has_default = self._write_to_conf = True
3525*10465441SEvalZero
3526*10465441SEvalZero                        val = val_sym.str_value
3527*10465441SEvalZero
3528*10465441SEvalZero                        if _is_base_n(val, base):
3529*10465441SEvalZero                            val_num = int(val, base)
3530*10465441SEvalZero                        else:
3531*10465441SEvalZero                            val_num = 0  # strtoll() on empty string
3532*10465441SEvalZero
3533*10465441SEvalZero                        break
3534*10465441SEvalZero                else:
3535*10465441SEvalZero                    val_num = 0  # strtoll() on empty string
3536*10465441SEvalZero
3537*10465441SEvalZero                # This clamping procedure runs even if there's no default
3538*10465441SEvalZero                if has_active_range:
3539*10465441SEvalZero                    clamp = None
3540*10465441SEvalZero                    if val_num < low:
3541*10465441SEvalZero                        clamp = low
3542*10465441SEvalZero                    elif val_num > high:
3543*10465441SEvalZero                        clamp = high
3544*10465441SEvalZero
3545*10465441SEvalZero                    if clamp is not None:
3546*10465441SEvalZero                        # The value is rewritten to a standard form if it is
3547*10465441SEvalZero                        # clamped
3548*10465441SEvalZero                        val = str(clamp) \
3549*10465441SEvalZero                              if self.orig_type is INT else \
3550*10465441SEvalZero                              hex(clamp)
3551*10465441SEvalZero
3552*10465441SEvalZero                        if has_default:
3553*10465441SEvalZero                            num2str = str if base == 10 else hex
3554*10465441SEvalZero                            self.kconfig._warn(
3555*10465441SEvalZero                                "default value {} on {} clamped to {} due to "
3556*10465441SEvalZero                                "being outside the active range ([{}, {}])"
3557*10465441SEvalZero                                .format(val_num, _name_and_loc(self),
3558*10465441SEvalZero                                        num2str(clamp), num2str(low),
3559*10465441SEvalZero                                        num2str(high)))
3560*10465441SEvalZero
3561*10465441SEvalZero        elif self.orig_type is STRING:
3562*10465441SEvalZero            if vis and self.user_value is not None:
3563*10465441SEvalZero                # If the symbol is visible and has a user value, use that
3564*10465441SEvalZero                val = self.user_value
3565*10465441SEvalZero            else:
3566*10465441SEvalZero                # Otherwise, look at defaults
3567*10465441SEvalZero                for val_sym, cond in self.defaults:
3568*10465441SEvalZero                    if expr_value(cond):
3569*10465441SEvalZero                        val = val_sym.str_value
3570*10465441SEvalZero                        self._write_to_conf = True
3571*10465441SEvalZero                        break
3572*10465441SEvalZero
3573*10465441SEvalZero        # env_var corresponds to SYMBOL_AUTO in the C implementation, and is
3574*10465441SEvalZero        # also set on the defconfig_list symbol there. Test for the
3575*10465441SEvalZero        # defconfig_list symbol explicitly instead here, to avoid a nonsensical
3576*10465441SEvalZero        # env_var setting and the defconfig_list symbol being printed
3577*10465441SEvalZero        # incorrectly. This code is pretty cold anyway.
3578*10465441SEvalZero        if self.env_var is not None or self is self.kconfig.defconfig_list:
3579*10465441SEvalZero            self._write_to_conf = False
3580*10465441SEvalZero
3581*10465441SEvalZero        self._cached_str_val = val
3582*10465441SEvalZero        return val
3583*10465441SEvalZero
3584*10465441SEvalZero    @property
3585*10465441SEvalZero    def tri_value(self):
3586*10465441SEvalZero        """
3587*10465441SEvalZero        See the class documentation.
3588*10465441SEvalZero        """
3589*10465441SEvalZero        if self._cached_tri_val is not None:
3590*10465441SEvalZero            return self._cached_tri_val
3591*10465441SEvalZero
3592*10465441SEvalZero        if self.orig_type not in (BOOL, TRISTATE):
3593*10465441SEvalZero            if self.orig_type is not UNKNOWN:
3594*10465441SEvalZero                # Would take some work to give the location here
3595*10465441SEvalZero                self.kconfig._warn(
3596*10465441SEvalZero                    "The {} symbol {} is being evaluated in a logical context "
3597*10465441SEvalZero                    "somewhere. It will always evaluate to n."
3598*10465441SEvalZero                    .format(TYPE_TO_STR[self.orig_type], _name_and_loc(self)))
3599*10465441SEvalZero
3600*10465441SEvalZero            self._cached_tri_val = 0
3601*10465441SEvalZero            return 0
3602*10465441SEvalZero
3603*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
3604*10465441SEvalZero        # function call (property magic)
3605*10465441SEvalZero        vis = self.visibility
3606*10465441SEvalZero        self._write_to_conf = (vis != 0)
3607*10465441SEvalZero
3608*10465441SEvalZero        val = 0
3609*10465441SEvalZero
3610*10465441SEvalZero        if not self.choice:
3611*10465441SEvalZero            # Non-choice symbol
3612*10465441SEvalZero
3613*10465441SEvalZero            if vis and self.user_value is not None:
3614*10465441SEvalZero                # If the symbol is visible and has a user value, use that
3615*10465441SEvalZero                val = min(self.user_value, vis)
3616*10465441SEvalZero
3617*10465441SEvalZero            else:
3618*10465441SEvalZero                # Otherwise, look at defaults and weak reverse dependencies
3619*10465441SEvalZero                # (implies)
3620*10465441SEvalZero
3621*10465441SEvalZero                for default, cond in self.defaults:
3622*10465441SEvalZero                    cond_val = expr_value(cond)
3623*10465441SEvalZero                    if cond_val:
3624*10465441SEvalZero                        val = min(expr_value(default), cond_val)
3625*10465441SEvalZero                        if val:
3626*10465441SEvalZero                            self._write_to_conf = True
3627*10465441SEvalZero                        break
3628*10465441SEvalZero
3629*10465441SEvalZero                # Weak reverse dependencies are only considered if our
3630*10465441SEvalZero                # direct dependencies are met
3631*10465441SEvalZero                weak_rev_dep_val = expr_value(self.weak_rev_dep)
3632*10465441SEvalZero                if weak_rev_dep_val and expr_value(self.direct_dep):
3633*10465441SEvalZero                    val = max(weak_rev_dep_val, val)
3634*10465441SEvalZero                    self._write_to_conf = True
3635*10465441SEvalZero
3636*10465441SEvalZero            # Reverse (select-related) dependencies take precedence
3637*10465441SEvalZero            rev_dep_val = expr_value(self.rev_dep)
3638*10465441SEvalZero            if rev_dep_val:
3639*10465441SEvalZero                if expr_value(self.direct_dep) < rev_dep_val:
3640*10465441SEvalZero                    self._warn_select_unsatisfied_deps()
3641*10465441SEvalZero
3642*10465441SEvalZero                val = max(rev_dep_val, val)
3643*10465441SEvalZero                self._write_to_conf = True
3644*10465441SEvalZero
3645*10465441SEvalZero            # m is promoted to y for (1) bool symbols and (2) symbols with a
3646*10465441SEvalZero            # weak_rev_dep (from imply) of y
3647*10465441SEvalZero            if val == 1 and \
3648*10465441SEvalZero               (self.type is BOOL or expr_value(self.weak_rev_dep) == 2):
3649*10465441SEvalZero                val = 2
3650*10465441SEvalZero
3651*10465441SEvalZero        elif vis == 2:
3652*10465441SEvalZero            # Visible choice symbol in y-mode choice. The choice mode limits
3653*10465441SEvalZero            # the visibility of choice symbols, so it's sufficient to just
3654*10465441SEvalZero            # check the visibility of the choice symbols themselves.
3655*10465441SEvalZero            val = 2 if self.choice.selection is self else 0
3656*10465441SEvalZero
3657*10465441SEvalZero        elif vis and self.user_value:
3658*10465441SEvalZero            # Visible choice symbol in m-mode choice, with set non-0 user value
3659*10465441SEvalZero            val = 1
3660*10465441SEvalZero
3661*10465441SEvalZero        self._cached_tri_val = val
3662*10465441SEvalZero        return val
3663*10465441SEvalZero
3664*10465441SEvalZero    @property
3665*10465441SEvalZero    def assignable(self):
3666*10465441SEvalZero        """
3667*10465441SEvalZero        See the class documentation.
3668*10465441SEvalZero        """
3669*10465441SEvalZero        if self._cached_assignable is None:
3670*10465441SEvalZero            self._cached_assignable = self._assignable()
3671*10465441SEvalZero
3672*10465441SEvalZero        return self._cached_assignable
3673*10465441SEvalZero
3674*10465441SEvalZero    @property
3675*10465441SEvalZero    def visibility(self):
3676*10465441SEvalZero        """
3677*10465441SEvalZero        See the class documentation.
3678*10465441SEvalZero        """
3679*10465441SEvalZero        if self._cached_vis is None:
3680*10465441SEvalZero            self._cached_vis = _visibility(self)
3681*10465441SEvalZero
3682*10465441SEvalZero        return self._cached_vis
3683*10465441SEvalZero
3684*10465441SEvalZero    @property
3685*10465441SEvalZero    def config_string(self):
3686*10465441SEvalZero        """
3687*10465441SEvalZero        See the class documentation.
3688*10465441SEvalZero        """
3689*10465441SEvalZero        # Note: _write_to_conf is determined when the value is calculated. This
3690*10465441SEvalZero        # is a hidden function call due to property magic.
3691*10465441SEvalZero        val = self.str_value
3692*10465441SEvalZero        if not self._write_to_conf:
3693*10465441SEvalZero            return ""
3694*10465441SEvalZero
3695*10465441SEvalZero        if self.orig_type in (BOOL, TRISTATE):
3696*10465441SEvalZero            return "{}{}={}\n" \
3697*10465441SEvalZero                   .format(self.kconfig.config_prefix, self.name, val) \
3698*10465441SEvalZero                   if val != "n" else \
3699*10465441SEvalZero                   "# {}{} is not set\n" \
3700*10465441SEvalZero                   .format(self.kconfig.config_prefix, self.name)
3701*10465441SEvalZero
3702*10465441SEvalZero        if self.orig_type in (INT, HEX):
3703*10465441SEvalZero            return "{}{}={}\n" \
3704*10465441SEvalZero                   .format(self.kconfig.config_prefix, self.name, val)
3705*10465441SEvalZero
3706*10465441SEvalZero        if self.orig_type is STRING:
3707*10465441SEvalZero            return '{}{}="{}"\n' \
3708*10465441SEvalZero                   .format(self.kconfig.config_prefix, self.name, escape(val))
3709*10465441SEvalZero
3710*10465441SEvalZero        _internal_error("Internal error while creating .config: unknown "
3711*10465441SEvalZero                        'type "{}".'.format(self.orig_type))
3712*10465441SEvalZero
3713*10465441SEvalZero    def set_value(self, value):
3714*10465441SEvalZero        """
3715*10465441SEvalZero        Sets the user value of the symbol.
3716*10465441SEvalZero
3717*10465441SEvalZero        Equal in effect to assigning the value to the symbol within a .config
3718*10465441SEvalZero        file. For bool and tristate symbols, use the 'assignable' attribute to
3719*10465441SEvalZero        check which values can currently be assigned. Setting values outside
3720*10465441SEvalZero        'assignable' will cause Symbol.user_value to differ from
3721*10465441SEvalZero        Symbol.str/tri_value (be truncated down or up).
3722*10465441SEvalZero
3723*10465441SEvalZero        Setting a choice symbol to 2 (y) sets Choice.user_selection to the
3724*10465441SEvalZero        choice symbol in addition to setting Symbol.user_value.
3725*10465441SEvalZero        Choice.user_selection is considered when the choice is in y mode (the
3726*10465441SEvalZero        "normal" mode).
3727*10465441SEvalZero
3728*10465441SEvalZero        Other symbols that depend (possibly indirectly) on this symbol are
3729*10465441SEvalZero        automatically recalculated to reflect the assigned value.
3730*10465441SEvalZero
3731*10465441SEvalZero        value:
3732*10465441SEvalZero          The user value to give to the symbol. For bool and tristate symbols,
3733*10465441SEvalZero          n/m/y can be specified either as 0/1/2 (the usual format for tristate
3734*10465441SEvalZero          values in Kconfiglib) or as one of the strings "n"/"m"/"y". For other
3735*10465441SEvalZero          symbol types, pass a string.
3736*10465441SEvalZero
3737*10465441SEvalZero          Values that are invalid for the type (such as "foo" or 1 (m) for a
3738*10465441SEvalZero          BOOL or "0x123" for an INT) are ignored and won't be stored in
3739*10465441SEvalZero          Symbol.user_value. Kconfiglib will print a warning by default for
3740*10465441SEvalZero          invalid assignments, and set_value() will return False.
3741*10465441SEvalZero
3742*10465441SEvalZero        Returns True if the value is valid for the type of the symbol, and
3743*10465441SEvalZero        False otherwise. This only looks at the form of the value. For BOOL and
3744*10465441SEvalZero        TRISTATE symbols, check the Symbol.assignable attribute to see what
3745*10465441SEvalZero        values are currently in range and would actually be reflected in the
3746*10465441SEvalZero        value of the symbol. For other symbol types, check whether the
3747*10465441SEvalZero        visibility is non-n.
3748*10465441SEvalZero        """
3749*10465441SEvalZero        # If the new user value matches the old, nothing changes, and we can
3750*10465441SEvalZero        # save some work.
3751*10465441SEvalZero        #
3752*10465441SEvalZero        # This optimization is skipped for choice symbols: Setting a choice
3753*10465441SEvalZero        # symbol's user value to y might change the state of the choice, so it
3754*10465441SEvalZero        # wouldn't be safe (symbol user values always match the values set in a
3755*10465441SEvalZero        # .config file or via set_value(), and are never implicitly updated).
3756*10465441SEvalZero        if value == self.user_value and not self.choice:
3757*10465441SEvalZero            self._was_set = True
3758*10465441SEvalZero            return True
3759*10465441SEvalZero
3760*10465441SEvalZero        # Check if the value is valid for our type
3761*10465441SEvalZero        if not (self.orig_type is BOOL     and value in (0, 2, "n", "y")         or
3762*10465441SEvalZero                self.orig_type is TRISTATE and value in (0, 1, 2, "n", "m", "y") or
3763*10465441SEvalZero                (isinstance(value, str)    and
3764*10465441SEvalZero                 (self.orig_type is STRING                        or
3765*10465441SEvalZero                  self.orig_type is INT and _is_base_n(value, 10) or
3766*10465441SEvalZero                  self.orig_type is HEX and _is_base_n(value, 16)
3767*10465441SEvalZero                                        and int(value, 16) >= 0))):
3768*10465441SEvalZero
3769*10465441SEvalZero            # Display tristate values as n, m, y in the warning
3770*10465441SEvalZero            self.kconfig._warn(
3771*10465441SEvalZero                "the value {} is invalid for {}, which has type {} -- "
3772*10465441SEvalZero                "assignment ignored"
3773*10465441SEvalZero                .format(TRI_TO_STR[value] if value in (0, 1, 2) else
3774*10465441SEvalZero                            "'{}'".format(value),
3775*10465441SEvalZero                        _name_and_loc(self), TYPE_TO_STR[self.orig_type]))
3776*10465441SEvalZero
3777*10465441SEvalZero            return False
3778*10465441SEvalZero
3779*10465441SEvalZero        if self.orig_type in (BOOL, TRISTATE) and value in ("n", "m", "y"):
3780*10465441SEvalZero            value = STR_TO_TRI[value]
3781*10465441SEvalZero
3782*10465441SEvalZero        self.user_value = value
3783*10465441SEvalZero        self._was_set = True
3784*10465441SEvalZero
3785*10465441SEvalZero        if self.choice and value == 2:
3786*10465441SEvalZero            # Setting a choice symbol to y makes it the user selection of the
3787*10465441SEvalZero            # choice. Like for symbol user values, the user selection is not
3788*10465441SEvalZero            # guaranteed to match the actual selection of the choice, as
3789*10465441SEvalZero            # dependencies come into play.
3790*10465441SEvalZero            self.choice.user_selection = self
3791*10465441SEvalZero            self.choice._was_set = True
3792*10465441SEvalZero            self.choice._rec_invalidate()
3793*10465441SEvalZero        else:
3794*10465441SEvalZero            self._rec_invalidate_if_has_prompt()
3795*10465441SEvalZero
3796*10465441SEvalZero        return True
3797*10465441SEvalZero
3798*10465441SEvalZero    def unset_value(self):
3799*10465441SEvalZero        """
3800*10465441SEvalZero        Resets the user value of the symbol, as if the symbol had never gotten
3801*10465441SEvalZero        a user value via Kconfig.load_config() or Symbol.set_value().
3802*10465441SEvalZero        """
3803*10465441SEvalZero        if self.user_value is not None:
3804*10465441SEvalZero            self.user_value = None
3805*10465441SEvalZero            self._rec_invalidate_if_has_prompt()
3806*10465441SEvalZero
3807*10465441SEvalZero    @property
3808*10465441SEvalZero    def referenced(self):
3809*10465441SEvalZero        """
3810*10465441SEvalZero        See the class documentation.
3811*10465441SEvalZero        """
3812*10465441SEvalZero        res = set()
3813*10465441SEvalZero        for node in self.nodes:
3814*10465441SEvalZero            res |= node.referenced
3815*10465441SEvalZero
3816*10465441SEvalZero        return res
3817*10465441SEvalZero
3818*10465441SEvalZero    def __repr__(self):
3819*10465441SEvalZero        """
3820*10465441SEvalZero        Returns a string with information about the symbol (including its name,
3821*10465441SEvalZero        value, visibility, and location(s)) when it is evaluated on e.g. the
3822*10465441SEvalZero        interactive Python prompt.
3823*10465441SEvalZero        """
3824*10465441SEvalZero        fields = []
3825*10465441SEvalZero
3826*10465441SEvalZero        fields.append("symbol " + self.name)
3827*10465441SEvalZero        fields.append(TYPE_TO_STR[self.type])
3828*10465441SEvalZero
3829*10465441SEvalZero        for node in self.nodes:
3830*10465441SEvalZero            if node.prompt:
3831*10465441SEvalZero                fields.append('"{}"'.format(node.prompt[0]))
3832*10465441SEvalZero
3833*10465441SEvalZero        # Only add quotes for non-bool/tristate symbols
3834*10465441SEvalZero        fields.append("value " +
3835*10465441SEvalZero                      (self.str_value
3836*10465441SEvalZero                       if self.orig_type in (BOOL, TRISTATE) else
3837*10465441SEvalZero                       '"{}"'.format(self.str_value)))
3838*10465441SEvalZero
3839*10465441SEvalZero        if not self.is_constant:
3840*10465441SEvalZero            # These aren't helpful to show for constant symbols
3841*10465441SEvalZero
3842*10465441SEvalZero            if self.user_value is not None:
3843*10465441SEvalZero                # Only add quotes for non-bool/tristate symbols
3844*10465441SEvalZero                fields.append("user value " +
3845*10465441SEvalZero                              (TRI_TO_STR[self.user_value]
3846*10465441SEvalZero                               if self.orig_type in (BOOL, TRISTATE) else
3847*10465441SEvalZero                               '"{}"'.format(self.user_value)))
3848*10465441SEvalZero
3849*10465441SEvalZero            fields.append("visibility " + TRI_TO_STR[self.visibility])
3850*10465441SEvalZero
3851*10465441SEvalZero            if self.choice:
3852*10465441SEvalZero                fields.append("choice symbol")
3853*10465441SEvalZero
3854*10465441SEvalZero            if self.is_allnoconfig_y:
3855*10465441SEvalZero                fields.append("allnoconfig_y")
3856*10465441SEvalZero
3857*10465441SEvalZero            if self is self.kconfig.defconfig_list:
3858*10465441SEvalZero                fields.append("is the defconfig_list symbol")
3859*10465441SEvalZero
3860*10465441SEvalZero            if self.env_var is not None:
3861*10465441SEvalZero                fields.append("from environment variable " + self.env_var)
3862*10465441SEvalZero
3863*10465441SEvalZero            if self is self.kconfig.modules:
3864*10465441SEvalZero                fields.append("is the modules symbol")
3865*10465441SEvalZero
3866*10465441SEvalZero            fields.append("direct deps " +
3867*10465441SEvalZero                          TRI_TO_STR[expr_value(self.direct_dep)])
3868*10465441SEvalZero
3869*10465441SEvalZero        if self.nodes:
3870*10465441SEvalZero            for node in self.nodes:
3871*10465441SEvalZero                fields.append("{}:{}".format(node.filename, node.linenr))
3872*10465441SEvalZero        else:
3873*10465441SEvalZero            if self.is_constant:
3874*10465441SEvalZero                fields.append("constant")
3875*10465441SEvalZero            else:
3876*10465441SEvalZero                fields.append("undefined")
3877*10465441SEvalZero
3878*10465441SEvalZero        return "<{}>".format(", ".join(fields))
3879*10465441SEvalZero
3880*10465441SEvalZero    def __str__(self):
3881*10465441SEvalZero        """
3882*10465441SEvalZero        Returns a string representation of the symbol when it is printed,
3883*10465441SEvalZero        matching the Kconfig format, with parent dependencies propagated.
3884*10465441SEvalZero
3885*10465441SEvalZero        The string is constructed by joining the strings returned by
3886*10465441SEvalZero        MenuNode.__str__() for each of the symbol's menu nodes, so symbols
3887*10465441SEvalZero        defined in multiple locations will return a string with all
3888*10465441SEvalZero        definitions.
3889*10465441SEvalZero
3890*10465441SEvalZero        An empty string is returned for undefined and constant symbols.
3891*10465441SEvalZero        """
3892*10465441SEvalZero        return self.custom_str(standard_sc_expr_str)
3893*10465441SEvalZero
3894*10465441SEvalZero    def custom_str(self, sc_expr_str_fn):
3895*10465441SEvalZero        """
3896*10465441SEvalZero        Works like Symbol.__str__(), but allows a custom format to be used for
3897*10465441SEvalZero        all symbol/choice references. See expr_str().
3898*10465441SEvalZero        """
3899*10465441SEvalZero        return "\n".join(node.custom_str(sc_expr_str_fn)
3900*10465441SEvalZero                         for node in self.nodes)
3901*10465441SEvalZero
3902*10465441SEvalZero    #
3903*10465441SEvalZero    # Private methods
3904*10465441SEvalZero    #
3905*10465441SEvalZero
3906*10465441SEvalZero    def __init__(self):
3907*10465441SEvalZero        """
3908*10465441SEvalZero        Symbol constructor -- not intended to be called directly by Kconfiglib
3909*10465441SEvalZero        clients.
3910*10465441SEvalZero        """
3911*10465441SEvalZero        # These attributes are always set on the instance from outside and
3912*10465441SEvalZero        # don't need defaults:
3913*10465441SEvalZero        #   kconfig
3914*10465441SEvalZero        #   direct_dep
3915*10465441SEvalZero        #   is_constant
3916*10465441SEvalZero        #   name
3917*10465441SEvalZero        #   rev_dep
3918*10465441SEvalZero        #   weak_rev_dep
3919*10465441SEvalZero
3920*10465441SEvalZero        self.orig_type = UNKNOWN
3921*10465441SEvalZero        self.defaults = []
3922*10465441SEvalZero        self.selects = []
3923*10465441SEvalZero        self.implies = []
3924*10465441SEvalZero        self.ranges = []
3925*10465441SEvalZero
3926*10465441SEvalZero        self.nodes = []
3927*10465441SEvalZero
3928*10465441SEvalZero        self.user_value = \
3929*10465441SEvalZero        self.choice = \
3930*10465441SEvalZero        self.env_var = \
3931*10465441SEvalZero        self._cached_str_val = self._cached_tri_val = self._cached_vis = \
3932*10465441SEvalZero        self._cached_assignable = None
3933*10465441SEvalZero
3934*10465441SEvalZero        # _write_to_conf is calculated along with the value. If True, the
3935*10465441SEvalZero        # Symbol gets a .config entry.
3936*10465441SEvalZero
3937*10465441SEvalZero        self.is_allnoconfig_y = \
3938*10465441SEvalZero        self._was_set = \
3939*10465441SEvalZero        self._write_to_conf = False
3940*10465441SEvalZero
3941*10465441SEvalZero        # See Kconfig._build_dep()
3942*10465441SEvalZero        self._dependents = set()
3943*10465441SEvalZero
3944*10465441SEvalZero        # Used during dependency loop detection and (independently) in
3945*10465441SEvalZero        # node_iter()
3946*10465441SEvalZero        self._visited = 0
3947*10465441SEvalZero
3948*10465441SEvalZero    def _assignable(self):
3949*10465441SEvalZero        # Worker function for the 'assignable' attribute
3950*10465441SEvalZero
3951*10465441SEvalZero        if self.orig_type not in (BOOL, TRISTATE):
3952*10465441SEvalZero            return ()
3953*10465441SEvalZero
3954*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
3955*10465441SEvalZero        # function call (property magic)
3956*10465441SEvalZero        vis = self.visibility
3957*10465441SEvalZero
3958*10465441SEvalZero        if not vis:
3959*10465441SEvalZero            return ()
3960*10465441SEvalZero
3961*10465441SEvalZero        rev_dep_val = expr_value(self.rev_dep)
3962*10465441SEvalZero
3963*10465441SEvalZero        if vis == 2:
3964*10465441SEvalZero            if self.choice:
3965*10465441SEvalZero                return (2,)
3966*10465441SEvalZero
3967*10465441SEvalZero            if not rev_dep_val:
3968*10465441SEvalZero                if self.type is BOOL or expr_value(self.weak_rev_dep) == 2:
3969*10465441SEvalZero                    return (0, 2)
3970*10465441SEvalZero                return (0, 1, 2)
3971*10465441SEvalZero
3972*10465441SEvalZero            if rev_dep_val == 2:
3973*10465441SEvalZero                return (2,)
3974*10465441SEvalZero
3975*10465441SEvalZero            # rev_dep_val == 1
3976*10465441SEvalZero
3977*10465441SEvalZero            if self.type is BOOL or expr_value(self.weak_rev_dep) == 2:
3978*10465441SEvalZero                return (2,)
3979*10465441SEvalZero            return (1, 2)
3980*10465441SEvalZero
3981*10465441SEvalZero        # vis == 1
3982*10465441SEvalZero
3983*10465441SEvalZero        # Must be a tristate here, because bool m visibility gets promoted to y
3984*10465441SEvalZero
3985*10465441SEvalZero        if not rev_dep_val:
3986*10465441SEvalZero            return (0, 1) if expr_value(self.weak_rev_dep) != 2 else (0, 2)
3987*10465441SEvalZero
3988*10465441SEvalZero        if rev_dep_val == 2:
3989*10465441SEvalZero            return (2,)
3990*10465441SEvalZero
3991*10465441SEvalZero        # vis == rev_dep_val == 1
3992*10465441SEvalZero
3993*10465441SEvalZero        return (1,)
3994*10465441SEvalZero
3995*10465441SEvalZero    def _invalidate(self):
3996*10465441SEvalZero        # Marks the symbol as needing to be recalculated
3997*10465441SEvalZero
3998*10465441SEvalZero        self._cached_str_val = self._cached_tri_val = self._cached_vis = \
3999*10465441SEvalZero            self._cached_assignable = None
4000*10465441SEvalZero
4001*10465441SEvalZero    def _rec_invalidate(self):
4002*10465441SEvalZero        # Invalidates the symbol and all items that (possibly) depend on it
4003*10465441SEvalZero
4004*10465441SEvalZero        if self is self.kconfig.modules:
4005*10465441SEvalZero            # Invalidating MODULES has wide-ranging effects
4006*10465441SEvalZero            self.kconfig._invalidate_all()
4007*10465441SEvalZero        else:
4008*10465441SEvalZero            self._invalidate()
4009*10465441SEvalZero
4010*10465441SEvalZero            for item in self._dependents:
4011*10465441SEvalZero                # _cached_vis doubles as a flag that tells us whether 'item'
4012*10465441SEvalZero                # has cached values, because it's calculated as a side effect
4013*10465441SEvalZero                # of calculating all other (non-constant) cached values.
4014*10465441SEvalZero                #
4015*10465441SEvalZero                # If item._cached_vis is None, it means there can't be cached
4016*10465441SEvalZero                # values on other items that depend on 'item', because if there
4017*10465441SEvalZero                # were, some value on 'item' would have been calculated and
4018*10465441SEvalZero                # item._cached_vis set as a side effect. It's therefore safe to
4019*10465441SEvalZero                # stop the invalidation at symbols with _cached_vis None.
4020*10465441SEvalZero                #
4021*10465441SEvalZero                # This approach massively speeds up scripts that set a lot of
4022*10465441SEvalZero                # values, vs simply invalidating all possibly dependent symbols
4023*10465441SEvalZero                # (even when you already have a list of all the dependent
4024*10465441SEvalZero                # symbols, because some symbols get huge dependency trees).
4025*10465441SEvalZero                #
4026*10465441SEvalZero                # This gracefully handles dependency loops too, which is nice
4027*10465441SEvalZero                # for choices, where the choice depends on the choice symbols
4028*10465441SEvalZero                # and vice versa.
4029*10465441SEvalZero                if item._cached_vis is not None:
4030*10465441SEvalZero                    item._rec_invalidate()
4031*10465441SEvalZero
4032*10465441SEvalZero    def _rec_invalidate_if_has_prompt(self):
4033*10465441SEvalZero        # Invalidates the symbol and its dependent symbols, but only if the
4034*10465441SEvalZero        # symbol has a prompt. User values never have an effect on promptless
4035*10465441SEvalZero        # symbols, so we skip invalidation for them as an optimization.
4036*10465441SEvalZero        #
4037*10465441SEvalZero        # This also prevents constant (quoted) symbols from being invalidated
4038*10465441SEvalZero        # if set_value() is called on them, which would cause them to lose
4039*10465441SEvalZero        # their value and break things.
4040*10465441SEvalZero        #
4041*10465441SEvalZero        # Prints a warning if the symbol has no prompt. In some contexts (e.g.
4042*10465441SEvalZero        # when loading a .config files) assignments to promptless symbols are
4043*10465441SEvalZero        # normal and expected, so the warning can be disabled.
4044*10465441SEvalZero
4045*10465441SEvalZero        for node in self.nodes:
4046*10465441SEvalZero            if node.prompt:
4047*10465441SEvalZero                self._rec_invalidate()
4048*10465441SEvalZero                return
4049*10465441SEvalZero
4050*10465441SEvalZero        if self.kconfig._warn_for_no_prompt:
4051*10465441SEvalZero            self.kconfig._warn(_name_and_loc(self) + " has no prompt, meaning "
4052*10465441SEvalZero                               "user values have no effect on it")
4053*10465441SEvalZero
4054*10465441SEvalZero    def _str_default(self):
4055*10465441SEvalZero        # write_min_config() helper function. Returns the value the symbol
4056*10465441SEvalZero        # would get from defaults if it didn't have a user value. Uses exactly
4057*10465441SEvalZero        # the same algorithm as the C implementation (though a bit cleaned up),
4058*10465441SEvalZero        # for compatibility.
4059*10465441SEvalZero
4060*10465441SEvalZero        if self.orig_type in (BOOL, TRISTATE):
4061*10465441SEvalZero            val = 0
4062*10465441SEvalZero
4063*10465441SEvalZero            # Defaults, selects, and implies do not affect choice symbols
4064*10465441SEvalZero            if not self.choice:
4065*10465441SEvalZero                for default, cond in self.defaults:
4066*10465441SEvalZero                    cond_val = expr_value(cond)
4067*10465441SEvalZero                    if cond_val:
4068*10465441SEvalZero                        val = min(expr_value(default), cond_val)
4069*10465441SEvalZero                        break
4070*10465441SEvalZero
4071*10465441SEvalZero                val = max(expr_value(self.rev_dep),
4072*10465441SEvalZero                          expr_value(self.weak_rev_dep),
4073*10465441SEvalZero                          val)
4074*10465441SEvalZero
4075*10465441SEvalZero                # Transpose mod to yes if type is bool (possibly due to modules
4076*10465441SEvalZero                # being disabled)
4077*10465441SEvalZero                if val == 1 and self.type is BOOL:
4078*10465441SEvalZero                    val = 2
4079*10465441SEvalZero
4080*10465441SEvalZero            return TRI_TO_STR[val]
4081*10465441SEvalZero
4082*10465441SEvalZero        if self.orig_type in (STRING, INT, HEX):
4083*10465441SEvalZero            for default, cond in self.defaults:
4084*10465441SEvalZero                if expr_value(cond):
4085*10465441SEvalZero                    return default.str_value
4086*10465441SEvalZero
4087*10465441SEvalZero        return ""
4088*10465441SEvalZero
4089*10465441SEvalZero    def _warn_select_unsatisfied_deps(self):
4090*10465441SEvalZero        # Helper for printing an informative warning when a symbol with
4091*10465441SEvalZero        # unsatisfied direct dependencies (dependencies from 'depends on', ifs,
4092*10465441SEvalZero        # and menus) is selected by some other symbol. Also warn if a symbol
4093*10465441SEvalZero        # whose direct dependencies evaluate to m is selected to y.
4094*10465441SEvalZero
4095*10465441SEvalZero        msg = "{} has direct dependencies {} with value {}, but is " \
4096*10465441SEvalZero              "currently being {}-selected by the following symbols:" \
4097*10465441SEvalZero              .format(_name_and_loc(self), expr_str(self.direct_dep),
4098*10465441SEvalZero                      TRI_TO_STR[expr_value(self.direct_dep)],
4099*10465441SEvalZero                      TRI_TO_STR[expr_value(self.rev_dep)])
4100*10465441SEvalZero
4101*10465441SEvalZero        # The reverse dependencies from each select are ORed together
4102*10465441SEvalZero        for select in split_expr(self.rev_dep, OR):
4103*10465441SEvalZero            if expr_value(select) <= expr_value(self.direct_dep):
4104*10465441SEvalZero                # Only include selects that exceed the direct dependencies
4105*10465441SEvalZero                continue
4106*10465441SEvalZero
4107*10465441SEvalZero            # - 'select A if B' turns into A && B
4108*10465441SEvalZero            # - 'select A' just turns into A
4109*10465441SEvalZero            #
4110*10465441SEvalZero            # In both cases, we can split on AND and pick the first operand
4111*10465441SEvalZero            selecting_sym = split_expr(select, AND)[0]
4112*10465441SEvalZero
4113*10465441SEvalZero            msg += "\n - {}, with value {}, direct dependencies {} " \
4114*10465441SEvalZero                   "(value: {})" \
4115*10465441SEvalZero                   .format(_name_and_loc(selecting_sym),
4116*10465441SEvalZero                           selecting_sym.str_value,
4117*10465441SEvalZero                           expr_str(selecting_sym.direct_dep),
4118*10465441SEvalZero                           TRI_TO_STR[expr_value(selecting_sym.direct_dep)])
4119*10465441SEvalZero
4120*10465441SEvalZero            if isinstance(select, tuple):
4121*10465441SEvalZero                msg += ", and select condition {} (value: {})" \
4122*10465441SEvalZero                       .format(expr_str(select[2]),
4123*10465441SEvalZero                               TRI_TO_STR[expr_value(select[2])])
4124*10465441SEvalZero
4125*10465441SEvalZero        self.kconfig._warn(msg)
4126*10465441SEvalZero
4127*10465441SEvalZeroclass Choice(object):
4128*10465441SEvalZero    """
4129*10465441SEvalZero    Represents a choice statement:
4130*10465441SEvalZero
4131*10465441SEvalZero      choice
4132*10465441SEvalZero          ...
4133*10465441SEvalZero      endchoice
4134*10465441SEvalZero
4135*10465441SEvalZero    The following attributes are available on Choice instances. They should be
4136*10465441SEvalZero    treated as read-only, and some are implemented through @property magic (but
4137*10465441SEvalZero    are still efficient to access due to internal caching).
4138*10465441SEvalZero
4139*10465441SEvalZero    Note: Prompts, help texts, and locations are stored in the Choice's
4140*10465441SEvalZero    MenuNode(s) rather than in the Choice itself. Check the MenuNode class and
4141*10465441SEvalZero    the Choice.nodes attribute. This organization matches the C tools.
4142*10465441SEvalZero
4143*10465441SEvalZero    name:
4144*10465441SEvalZero      The name of the choice, e.g. "FOO" for 'choice FOO', or None if the
4145*10465441SEvalZero      Choice has no name. I can't remember ever seeing named choices in
4146*10465441SEvalZero      practice, but the C tools support them too.
4147*10465441SEvalZero
4148*10465441SEvalZero    type:
4149*10465441SEvalZero      The type of the choice. One of BOOL, TRISTATE, UNKNOWN. UNKNOWN is for
4150*10465441SEvalZero      choices defined without a type where none of the contained symbols have a
4151*10465441SEvalZero      type either (otherwise the choice inherits the type of the first symbol
4152*10465441SEvalZero      defined with a type).
4153*10465441SEvalZero
4154*10465441SEvalZero      When running without modules (CONFIG_MODULES=n), TRISTATE choices
4155*10465441SEvalZero      magically change type to BOOL. This matches the C tools, and makes sense
4156*10465441SEvalZero      for menuconfig-like functionality.
4157*10465441SEvalZero
4158*10465441SEvalZero    orig_type:
4159*10465441SEvalZero      The type as given in the Kconfig file, without any magic applied. Used
4160*10465441SEvalZero      when printing the choice.
4161*10465441SEvalZero
4162*10465441SEvalZero    tri_value:
4163*10465441SEvalZero      The tristate value (mode) of the choice. A choice can be in one of three
4164*10465441SEvalZero      modes:
4165*10465441SEvalZero
4166*10465441SEvalZero        0 (n) - The choice is disabled and no symbols can be selected. For
4167*10465441SEvalZero                visible choices, this mode is only possible for choices with
4168*10465441SEvalZero                the 'optional' flag set (see kconfig-language.txt).
4169*10465441SEvalZero
4170*10465441SEvalZero        1 (m) - Any number of choice symbols can be set to m, the rest will
4171*10465441SEvalZero                be n.
4172*10465441SEvalZero
4173*10465441SEvalZero        2 (y) - One symbol will be y, the rest n.
4174*10465441SEvalZero
4175*10465441SEvalZero      Only tristate choices can be in m mode. The visibility of the choice is
4176*10465441SEvalZero      an upper bound on the mode, and the mode in turn is an upper bound on the
4177*10465441SEvalZero      visibility of the choice symbols.
4178*10465441SEvalZero
4179*10465441SEvalZero      To change the mode, use Choice.set_value().
4180*10465441SEvalZero
4181*10465441SEvalZero      Implementation note:
4182*10465441SEvalZero        The C tools internally represent choices as a type of symbol, with
4183*10465441SEvalZero        special-casing in many code paths. This is why there is a lot of
4184*10465441SEvalZero        similarity to Symbol. The value (mode) of a choice is really just a
4185*10465441SEvalZero        normal symbol value, and an implicit reverse dependency forces its
4186*10465441SEvalZero        lower bound to m for visible non-optional choices (the reverse
4187*10465441SEvalZero        dependency is 'm && <visibility>').
4188*10465441SEvalZero
4189*10465441SEvalZero        Symbols within choices get the choice propagated as a dependency to
4190*10465441SEvalZero        their properties. This turns the mode of the choice into an upper bound
4191*10465441SEvalZero        on e.g. the visibility of choice symbols, and explains the gotcha
4192*10465441SEvalZero        related to printing choice symbols mentioned in the module docstring.
4193*10465441SEvalZero
4194*10465441SEvalZero        Kconfiglib uses a separate Choice class only because it makes the code
4195*10465441SEvalZero        and interface less confusing (especially in a user-facing interface).
4196*10465441SEvalZero        Corresponding attributes have the same name in the Symbol and Choice
4197*10465441SEvalZero        classes, for consistency and compatibility.
4198*10465441SEvalZero
4199*10465441SEvalZero    assignable:
4200*10465441SEvalZero      See the symbol class documentation. Gives the assignable values (modes).
4201*10465441SEvalZero
4202*10465441SEvalZero    visibility:
4203*10465441SEvalZero      See the Symbol class documentation. Acts on the value (mode).
4204*10465441SEvalZero
4205*10465441SEvalZero    selection:
4206*10465441SEvalZero      The Symbol instance of the currently selected symbol. None if the Choice
4207*10465441SEvalZero      is not in y mode or has no selected symbol (due to unsatisfied
4208*10465441SEvalZero      dependencies on choice symbols).
4209*10465441SEvalZero
4210*10465441SEvalZero      WARNING: Do not assign directly to this. It will break things. Call
4211*10465441SEvalZero      sym.set_value(2) on the choice symbol you want to select instead.
4212*10465441SEvalZero
4213*10465441SEvalZero    user_value:
4214*10465441SEvalZero      The value (mode) selected by the user through Choice.set_value(). Either
4215*10465441SEvalZero      0, 1, or 2, or None if the user hasn't selected a mode. See
4216*10465441SEvalZero      Symbol.user_value.
4217*10465441SEvalZero
4218*10465441SEvalZero      WARNING: Do not assign directly to this. It will break things. Use
4219*10465441SEvalZero      Choice.set_value() instead.
4220*10465441SEvalZero
4221*10465441SEvalZero    user_selection:
4222*10465441SEvalZero      The symbol selected by the user (by setting it to y). Ignored if the
4223*10465441SEvalZero      choice is not in y mode, but still remembered so that the choice "snaps
4224*10465441SEvalZero      back" to the user selection if the mode is changed back to y. This might
4225*10465441SEvalZero      differ from 'selection' due to unsatisfied dependencies.
4226*10465441SEvalZero
4227*10465441SEvalZero      WARNING: Do not assign directly to this. It will break things. Call
4228*10465441SEvalZero      sym.set_value(2) on the choice symbol to be selected instead.
4229*10465441SEvalZero
4230*10465441SEvalZero    syms:
4231*10465441SEvalZero      List of symbols contained in the choice.
4232*10465441SEvalZero
4233*10465441SEvalZero      Gotcha: If a symbol depends on the previous symbol within a choice so
4234*10465441SEvalZero      that an implicit menu is created, it won't be a choice symbol, and won't
4235*10465441SEvalZero      be included in 'syms'. There are real-world examples of this, and it was
4236*10465441SEvalZero      a PITA to support in older versions of Kconfiglib that didn't implement
4237*10465441SEvalZero      the menu structure.
4238*10465441SEvalZero
4239*10465441SEvalZero    nodes:
4240*10465441SEvalZero      A list of MenuNodes for this choice. In practice, the list will probably
4241*10465441SEvalZero      always contain a single MenuNode, but it is possible to give a choice a
4242*10465441SEvalZero      name and define it in multiple locations (I've never even seen a named
4243*10465441SEvalZero      choice though).
4244*10465441SEvalZero
4245*10465441SEvalZero    defaults:
4246*10465441SEvalZero      List of (symbol, cond) tuples for the choice's 'defaults' properties. For
4247*10465441SEvalZero      example, 'default A if B && C' is represented as (A, (AND, B, C)). If
4248*10465441SEvalZero      there is no condition, 'cond' is self.config.y.
4249*10465441SEvalZero
4250*10465441SEvalZero      Note that 'depends on' and parent dependencies are propagated to
4251*10465441SEvalZero      'default' conditions.
4252*10465441SEvalZero
4253*10465441SEvalZero    direct_dep:
4254*10465441SEvalZero      See Symbol.direct_dep.
4255*10465441SEvalZero
4256*10465441SEvalZero    referenced:
4257*10465441SEvalZero      A set() with all symbols referenced in the properties and property
4258*10465441SEvalZero      conditions of the choice.
4259*10465441SEvalZero
4260*10465441SEvalZero      Also includes dependencies inherited from surrounding menus and if's.
4261*10465441SEvalZero
4262*10465441SEvalZero    is_optional:
4263*10465441SEvalZero      True if the choice has the 'optional' flag set on it and can be in
4264*10465441SEvalZero      n mode.
4265*10465441SEvalZero
4266*10465441SEvalZero    kconfig:
4267*10465441SEvalZero      The Kconfig instance this choice is from.
4268*10465441SEvalZero    """
4269*10465441SEvalZero    __slots__ = (
4270*10465441SEvalZero        "_cached_assignable",
4271*10465441SEvalZero        "_cached_selection",
4272*10465441SEvalZero        "_cached_vis",
4273*10465441SEvalZero        "_dependents",
4274*10465441SEvalZero        "_visited",
4275*10465441SEvalZero        "_was_set",
4276*10465441SEvalZero        "defaults",
4277*10465441SEvalZero        "direct_dep",
4278*10465441SEvalZero        "is_constant",
4279*10465441SEvalZero        "is_optional",
4280*10465441SEvalZero        "kconfig",
4281*10465441SEvalZero        "name",
4282*10465441SEvalZero        "nodes",
4283*10465441SEvalZero        "orig_type",
4284*10465441SEvalZero        "syms",
4285*10465441SEvalZero        "user_selection",
4286*10465441SEvalZero        "user_value",
4287*10465441SEvalZero    )
4288*10465441SEvalZero
4289*10465441SEvalZero    #
4290*10465441SEvalZero    # Public interface
4291*10465441SEvalZero    #
4292*10465441SEvalZero
4293*10465441SEvalZero    @property
4294*10465441SEvalZero    def type(self):
4295*10465441SEvalZero        """
4296*10465441SEvalZero        Returns the type of the choice. See Symbol.type.
4297*10465441SEvalZero        """
4298*10465441SEvalZero        if self.orig_type is TRISTATE and not self.kconfig.modules.tri_value:
4299*10465441SEvalZero            return BOOL
4300*10465441SEvalZero
4301*10465441SEvalZero        return self.orig_type
4302*10465441SEvalZero
4303*10465441SEvalZero    @property
4304*10465441SEvalZero    def str_value(self):
4305*10465441SEvalZero        """
4306*10465441SEvalZero        See the class documentation.
4307*10465441SEvalZero        """
4308*10465441SEvalZero        return TRI_TO_STR[self.tri_value]
4309*10465441SEvalZero
4310*10465441SEvalZero    @property
4311*10465441SEvalZero    def tri_value(self):
4312*10465441SEvalZero        """
4313*10465441SEvalZero        See the class documentation.
4314*10465441SEvalZero        """
4315*10465441SEvalZero        # This emulates a reverse dependency of 'm && visibility' for
4316*10465441SEvalZero        # non-optional choices, which is how the C implementation does it
4317*10465441SEvalZero
4318*10465441SEvalZero        val = 0 if self.is_optional else 1
4319*10465441SEvalZero
4320*10465441SEvalZero        if self.user_value is not None:
4321*10465441SEvalZero            val = max(val, self.user_value)
4322*10465441SEvalZero
4323*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
4324*10465441SEvalZero        # function call (property magic)
4325*10465441SEvalZero        val = min(val, self.visibility)
4326*10465441SEvalZero
4327*10465441SEvalZero        # Promote m to y for boolean choices
4328*10465441SEvalZero        return 2 if val == 1 and self.type is BOOL else val
4329*10465441SEvalZero
4330*10465441SEvalZero    @property
4331*10465441SEvalZero    def assignable(self):
4332*10465441SEvalZero        """
4333*10465441SEvalZero        See the class documentation.
4334*10465441SEvalZero        """
4335*10465441SEvalZero        if self._cached_assignable is None:
4336*10465441SEvalZero            self._cached_assignable = self._assignable()
4337*10465441SEvalZero
4338*10465441SEvalZero        return self._cached_assignable
4339*10465441SEvalZero
4340*10465441SEvalZero    @property
4341*10465441SEvalZero    def visibility(self):
4342*10465441SEvalZero        """
4343*10465441SEvalZero        See the class documentation.
4344*10465441SEvalZero        """
4345*10465441SEvalZero        if self._cached_vis is None:
4346*10465441SEvalZero            self._cached_vis = _visibility(self)
4347*10465441SEvalZero
4348*10465441SEvalZero        return self._cached_vis
4349*10465441SEvalZero
4350*10465441SEvalZero    @property
4351*10465441SEvalZero    def selection(self):
4352*10465441SEvalZero        """
4353*10465441SEvalZero        See the class documentation.
4354*10465441SEvalZero        """
4355*10465441SEvalZero        if self._cached_selection is _NO_CACHED_SELECTION:
4356*10465441SEvalZero            self._cached_selection = self._selection()
4357*10465441SEvalZero
4358*10465441SEvalZero        return self._cached_selection
4359*10465441SEvalZero
4360*10465441SEvalZero    def set_value(self, value):
4361*10465441SEvalZero        """
4362*10465441SEvalZero        Sets the user value (mode) of the choice. Like for Symbol.set_value(),
4363*10465441SEvalZero        the visibility might truncate the value. Choices without the 'optional'
4364*10465441SEvalZero        attribute (is_optional) can never be in n mode, but 0/"n" is still
4365*10465441SEvalZero        accepted since it's not a malformed value (though it will have no
4366*10465441SEvalZero        effect).
4367*10465441SEvalZero
4368*10465441SEvalZero        Returns True if the value is valid for the type of the choice, and
4369*10465441SEvalZero        False otherwise. This only looks at the form of the value. Check the
4370*10465441SEvalZero        Choice.assignable attribute to see what values are currently in range
4371*10465441SEvalZero        and would actually be reflected in the mode of the choice.
4372*10465441SEvalZero        """
4373*10465441SEvalZero        if value == self.user_value:
4374*10465441SEvalZero            # We know the value must be valid if it was successfully set
4375*10465441SEvalZero            # previously
4376*10465441SEvalZero            self._was_set = True
4377*10465441SEvalZero            return True
4378*10465441SEvalZero
4379*10465441SEvalZero        if not ((self.orig_type is BOOL     and value in (0, 2, "n", "y")        ) or
4380*10465441SEvalZero                (self.orig_type is TRISTATE and value in (0, 1, 2, "n", "m", "y"))):
4381*10465441SEvalZero
4382*10465441SEvalZero            # Display tristate values as n, m, y in the warning
4383*10465441SEvalZero            self.kconfig._warn(
4384*10465441SEvalZero                "the value {} is invalid for {}, which has type {} -- "
4385*10465441SEvalZero                "assignment ignored"
4386*10465441SEvalZero                .format(TRI_TO_STR[value] if value in (0, 1, 2) else
4387*10465441SEvalZero                            "'{}'".format(value),
4388*10465441SEvalZero                        _name_and_loc(self),
4389*10465441SEvalZero                        TYPE_TO_STR[self.orig_type]))
4390*10465441SEvalZero
4391*10465441SEvalZero            return False
4392*10465441SEvalZero
4393*10465441SEvalZero        if value in ("n", "m", "y"):
4394*10465441SEvalZero            value = STR_TO_TRI[value]
4395*10465441SEvalZero
4396*10465441SEvalZero        self.user_value = value
4397*10465441SEvalZero        self._was_set = True
4398*10465441SEvalZero        self._rec_invalidate()
4399*10465441SEvalZero
4400*10465441SEvalZero        return True
4401*10465441SEvalZero
4402*10465441SEvalZero    def unset_value(self):
4403*10465441SEvalZero        """
4404*10465441SEvalZero        Resets the user value (mode) and user selection of the Choice, as if
4405*10465441SEvalZero        the user had never touched the mode or any of the choice symbols.
4406*10465441SEvalZero        """
4407*10465441SEvalZero        if self.user_value is not None or self.user_selection:
4408*10465441SEvalZero            self.user_value = self.user_selection = None
4409*10465441SEvalZero            self._rec_invalidate()
4410*10465441SEvalZero
4411*10465441SEvalZero    @property
4412*10465441SEvalZero    def referenced(self):
4413*10465441SEvalZero        """
4414*10465441SEvalZero        See the class documentation.
4415*10465441SEvalZero        """
4416*10465441SEvalZero        res = set()
4417*10465441SEvalZero        for node in self.nodes:
4418*10465441SEvalZero            res |= node.referenced
4419*10465441SEvalZero
4420*10465441SEvalZero        return res
4421*10465441SEvalZero
4422*10465441SEvalZero    def __repr__(self):
4423*10465441SEvalZero        """
4424*10465441SEvalZero        Returns a string with information about the choice when it is evaluated
4425*10465441SEvalZero        on e.g. the interactive Python prompt.
4426*10465441SEvalZero        """
4427*10465441SEvalZero        fields = []
4428*10465441SEvalZero
4429*10465441SEvalZero        fields.append("choice " + self.name if self.name else "choice")
4430*10465441SEvalZero        fields.append(TYPE_TO_STR[self.type])
4431*10465441SEvalZero
4432*10465441SEvalZero        for node in self.nodes:
4433*10465441SEvalZero            if node.prompt:
4434*10465441SEvalZero                fields.append('"{}"'.format(node.prompt[0]))
4435*10465441SEvalZero
4436*10465441SEvalZero        fields.append("mode " + self.str_value)
4437*10465441SEvalZero
4438*10465441SEvalZero        if self.user_value is not None:
4439*10465441SEvalZero            fields.append('user mode {}'.format(TRI_TO_STR[self.user_value]))
4440*10465441SEvalZero
4441*10465441SEvalZero        if self.selection:
4442*10465441SEvalZero            fields.append("{} selected".format(self.selection.name))
4443*10465441SEvalZero
4444*10465441SEvalZero        if self.user_selection:
4445*10465441SEvalZero            user_sel_str = "{} selected by user" \
4446*10465441SEvalZero                           .format(self.user_selection.name)
4447*10465441SEvalZero
4448*10465441SEvalZero            if self.selection is not self.user_selection:
4449*10465441SEvalZero                user_sel_str += " (overridden)"
4450*10465441SEvalZero
4451*10465441SEvalZero            fields.append(user_sel_str)
4452*10465441SEvalZero
4453*10465441SEvalZero        fields.append("visibility " + TRI_TO_STR[self.visibility])
4454*10465441SEvalZero
4455*10465441SEvalZero        if self.is_optional:
4456*10465441SEvalZero            fields.append("optional")
4457*10465441SEvalZero
4458*10465441SEvalZero        for node in self.nodes:
4459*10465441SEvalZero            fields.append("{}:{}".format(node.filename, node.linenr))
4460*10465441SEvalZero
4461*10465441SEvalZero        return "<{}>".format(", ".join(fields))
4462*10465441SEvalZero
4463*10465441SEvalZero    def __str__(self):
4464*10465441SEvalZero        """
4465*10465441SEvalZero        Returns a string representation of the choice when it is printed,
4466*10465441SEvalZero        matching the Kconfig format (though without the contained choice
4467*10465441SEvalZero        symbols).
4468*10465441SEvalZero
4469*10465441SEvalZero        See Symbol.__str__() as well.
4470*10465441SEvalZero        """
4471*10465441SEvalZero        return self.custom_str(standard_sc_expr_str)
4472*10465441SEvalZero
4473*10465441SEvalZero    def custom_str(self, sc_expr_str_fn):
4474*10465441SEvalZero        """
4475*10465441SEvalZero        Works like Choice.__str__(), but allows a custom format to be used for
4476*10465441SEvalZero        all symbol/choice references. See expr_str().
4477*10465441SEvalZero        """
4478*10465441SEvalZero        return "\n".join(node.custom_str(sc_expr_str_fn)
4479*10465441SEvalZero                         for node in self.nodes)
4480*10465441SEvalZero
4481*10465441SEvalZero    #
4482*10465441SEvalZero    # Private methods
4483*10465441SEvalZero    #
4484*10465441SEvalZero
4485*10465441SEvalZero    def __init__(self):
4486*10465441SEvalZero        """
4487*10465441SEvalZero        Choice constructor -- not intended to be called directly by Kconfiglib
4488*10465441SEvalZero        clients.
4489*10465441SEvalZero        """
4490*10465441SEvalZero        # These attributes are always set on the instance from outside and
4491*10465441SEvalZero        # don't need defaults:
4492*10465441SEvalZero        #   direct_dep
4493*10465441SEvalZero        #   kconfig
4494*10465441SEvalZero
4495*10465441SEvalZero        self.orig_type = UNKNOWN
4496*10465441SEvalZero        self.syms = []
4497*10465441SEvalZero        self.defaults = []
4498*10465441SEvalZero
4499*10465441SEvalZero        self.nodes = []
4500*10465441SEvalZero
4501*10465441SEvalZero        self.name = \
4502*10465441SEvalZero        self.user_value = self.user_selection = \
4503*10465441SEvalZero        self._cached_vis = self._cached_assignable = None
4504*10465441SEvalZero
4505*10465441SEvalZero        self._cached_selection = _NO_CACHED_SELECTION
4506*10465441SEvalZero
4507*10465441SEvalZero        # is_constant is checked by _make_depend_on(). Just set it to avoid
4508*10465441SEvalZero        # having to special-case choices.
4509*10465441SEvalZero        self.is_constant = self.is_optional = False
4510*10465441SEvalZero
4511*10465441SEvalZero        # See Kconfig._build_dep()
4512*10465441SEvalZero        self._dependents = set()
4513*10465441SEvalZero
4514*10465441SEvalZero        # Used during dependency loop detection
4515*10465441SEvalZero        self._visited = 0
4516*10465441SEvalZero
4517*10465441SEvalZero    def _assignable(self):
4518*10465441SEvalZero        # Worker function for the 'assignable' attribute
4519*10465441SEvalZero
4520*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
4521*10465441SEvalZero        # function call (property magic)
4522*10465441SEvalZero        vis = self.visibility
4523*10465441SEvalZero
4524*10465441SEvalZero        if not vis:
4525*10465441SEvalZero            return ()
4526*10465441SEvalZero
4527*10465441SEvalZero        if vis == 2:
4528*10465441SEvalZero            if not self.is_optional:
4529*10465441SEvalZero                return (2,) if self.type is BOOL else (1, 2)
4530*10465441SEvalZero            return (0, 2) if self.type is BOOL else (0, 1, 2)
4531*10465441SEvalZero
4532*10465441SEvalZero        # vis == 1
4533*10465441SEvalZero
4534*10465441SEvalZero        return (0, 1) if self.is_optional else (1,)
4535*10465441SEvalZero
4536*10465441SEvalZero    def _selection(self):
4537*10465441SEvalZero        # Worker function for the 'selection' attribute
4538*10465441SEvalZero
4539*10465441SEvalZero        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden
4540*10465441SEvalZero        # function call (property magic)
4541*10465441SEvalZero        if self.tri_value != 2:
4542*10465441SEvalZero            # Not in y mode, so no selection
4543*10465441SEvalZero            return None
4544*10465441SEvalZero
4545*10465441SEvalZero        # Use the user selection if it's visible
4546*10465441SEvalZero        if self.user_selection and self.user_selection.visibility:
4547*10465441SEvalZero            return self.user_selection
4548*10465441SEvalZero
4549*10465441SEvalZero        # Otherwise, check if we have a default
4550*10465441SEvalZero        return self._get_selection_from_defaults()
4551*10465441SEvalZero
4552*10465441SEvalZero    def _get_selection_from_defaults(self):
4553*10465441SEvalZero        # Check if we have a default
4554*10465441SEvalZero        for sym, cond in self.defaults:
4555*10465441SEvalZero            # The default symbol must be visible too
4556*10465441SEvalZero            if expr_value(cond) and sym.visibility:
4557*10465441SEvalZero                return sym
4558*10465441SEvalZero
4559*10465441SEvalZero        # Otherwise, pick the first visible symbol, if any
4560*10465441SEvalZero        for sym in self.syms:
4561*10465441SEvalZero            if sym.visibility:
4562*10465441SEvalZero                return sym
4563*10465441SEvalZero
4564*10465441SEvalZero        # Couldn't find a selection
4565*10465441SEvalZero        return None
4566*10465441SEvalZero
4567*10465441SEvalZero    def _invalidate(self):
4568*10465441SEvalZero        self._cached_vis = self._cached_assignable = None
4569*10465441SEvalZero        self._cached_selection = _NO_CACHED_SELECTION
4570*10465441SEvalZero
4571*10465441SEvalZero    def _rec_invalidate(self):
4572*10465441SEvalZero        # See Symbol._rec_invalidate()
4573*10465441SEvalZero
4574*10465441SEvalZero        self._invalidate()
4575*10465441SEvalZero
4576*10465441SEvalZero        for item in self._dependents:
4577*10465441SEvalZero            if item._cached_vis is not None:
4578*10465441SEvalZero                item._rec_invalidate()
4579*10465441SEvalZero
4580*10465441SEvalZeroclass MenuNode(object):
4581*10465441SEvalZero    """
4582*10465441SEvalZero    Represents a menu node in the configuration. This corresponds to an entry
4583*10465441SEvalZero    in e.g. the 'make menuconfig' interface, though non-visible choices, menus,
4584*10465441SEvalZero    and comments also get menu nodes. If a symbol or choice is defined in
4585*10465441SEvalZero    multiple locations, it gets one menu node for each location.
4586*10465441SEvalZero
4587*10465441SEvalZero    The top-level menu node, corresponding to the implicit top-level menu, is
4588*10465441SEvalZero    available in Kconfig.top_node.
4589*10465441SEvalZero
4590*10465441SEvalZero    The menu nodes for a Symbol or Choice can be found in the
4591*10465441SEvalZero    Symbol/Choice.nodes attribute. Menus and comments are represented as plain
4592*10465441SEvalZero    menu nodes, with their text stored in the prompt attribute (prompt[0]).
4593*10465441SEvalZero    This mirrors the C implementation.
4594*10465441SEvalZero
4595*10465441SEvalZero    The following attributes are available on MenuNode instances. They should
4596*10465441SEvalZero    be viewed as read-only.
4597*10465441SEvalZero
4598*10465441SEvalZero    item:
4599*10465441SEvalZero      Either a Symbol, a Choice, or one of the constants MENU and COMMENT.
4600*10465441SEvalZero      Menus and comments are represented as plain menu nodes. Ifs are collapsed
4601*10465441SEvalZero      (matching the C implementation) and do not appear in the final menu tree.
4602*10465441SEvalZero
4603*10465441SEvalZero    next:
4604*10465441SEvalZero      The following menu node. None if there is no following node.
4605*10465441SEvalZero
4606*10465441SEvalZero    list:
4607*10465441SEvalZero      The first child menu node. None if there are no children.
4608*10465441SEvalZero
4609*10465441SEvalZero      Choices and menus naturally have children, but Symbols can also have
4610*10465441SEvalZero      children because of menus created automatically from dependencies (see
4611*10465441SEvalZero      kconfig-language.txt).
4612*10465441SEvalZero
4613*10465441SEvalZero    parent:
4614*10465441SEvalZero      The parent menu node. None if there is no parent.
4615*10465441SEvalZero
4616*10465441SEvalZero    prompt:
4617*10465441SEvalZero      A (string, cond) tuple with the prompt for the menu node and its
4618*10465441SEvalZero      conditional expression (which is self.kconfig.y if there is no
4619*10465441SEvalZero      condition). None if there is no prompt.
4620*10465441SEvalZero
4621*10465441SEvalZero      For symbols and choices, the prompt is stored in the MenuNode rather than
4622*10465441SEvalZero      the Symbol or Choice instance. For menus and comments, the prompt holds
4623*10465441SEvalZero      the text.
4624*10465441SEvalZero
4625*10465441SEvalZero    defaults:
4626*10465441SEvalZero      The 'default' properties for this particular menu node. See
4627*10465441SEvalZero      symbol.defaults.
4628*10465441SEvalZero
4629*10465441SEvalZero      When evaluating defaults, you should use Symbol/Choice.defaults instead,
4630*10465441SEvalZero      as it include properties from all menu nodes (a symbol/choice can have
4631*10465441SEvalZero      multiple definition locations/menu nodes). MenuNode.defaults is meant for
4632*10465441SEvalZero      documentation generation.
4633*10465441SEvalZero
4634*10465441SEvalZero    selects:
4635*10465441SEvalZero      Like MenuNode.defaults, for selects.
4636*10465441SEvalZero
4637*10465441SEvalZero    implies:
4638*10465441SEvalZero      Like MenuNode.defaults, for implies.
4639*10465441SEvalZero
4640*10465441SEvalZero    ranges:
4641*10465441SEvalZero      Like MenuNode.defaults, for ranges.
4642*10465441SEvalZero
4643*10465441SEvalZero    help:
4644*10465441SEvalZero      The help text for the menu node for Symbols and Choices. None if there is
4645*10465441SEvalZero      no help text. Always stored in the node rather than the Symbol or Choice.
4646*10465441SEvalZero      It is possible to have a separate help text at each location if a symbol
4647*10465441SEvalZero      is defined in multiple locations.
4648*10465441SEvalZero
4649*10465441SEvalZero    dep:
4650*10465441SEvalZero      The 'depends on' dependencies for the menu node, or self.kconfig.y if
4651*10465441SEvalZero      there are no dependencies. Parent dependencies are propagated to this
4652*10465441SEvalZero      attribute, and this attribute is then in turn propagated to the
4653*10465441SEvalZero      properties of symbols and choices.
4654*10465441SEvalZero
4655*10465441SEvalZero      If a symbol or choice is defined in multiple locations, only the
4656*10465441SEvalZero      properties defined at a particular location get the corresponding
4657*10465441SEvalZero      MenuNode.dep dependencies propagated to them.
4658*10465441SEvalZero
4659*10465441SEvalZero    visibility:
4660*10465441SEvalZero      The 'visible if' dependencies for the menu node (which must represent a
4661*10465441SEvalZero      menu), or self.kconfig.y if there are no 'visible if' dependencies.
4662*10465441SEvalZero      'visible if' dependencies are recursively propagated to the prompts of
4663*10465441SEvalZero      symbols and choices within the menu.
4664*10465441SEvalZero
4665*10465441SEvalZero    referenced:
4666*10465441SEvalZero      A set() with all symbols and choices referenced in the properties and
4667*10465441SEvalZero      property conditions of the menu node.
4668*10465441SEvalZero
4669*10465441SEvalZero      Also includes dependencies inherited from surrounding menus and if's.
4670*10465441SEvalZero      Choices appear in the dependencies of choice symbols.
4671*10465441SEvalZero
4672*10465441SEvalZero    is_menuconfig:
4673*10465441SEvalZero      Set to True if the children of the menu node should be displayed in a
4674*10465441SEvalZero      separate menu. This is the case for the following items:
4675*10465441SEvalZero
4676*10465441SEvalZero        - Menus (node.item == MENU)
4677*10465441SEvalZero
4678*10465441SEvalZero        - Choices
4679*10465441SEvalZero
4680*10465441SEvalZero        - Symbols defined with the 'menuconfig' keyword. The children come from
4681*10465441SEvalZero          implicitly created submenus, and should be displayed in a separate
4682*10465441SEvalZero          menu rather than being indented.
4683*10465441SEvalZero
4684*10465441SEvalZero      'is_menuconfig' is just a hint on how to display the menu node. It's
4685*10465441SEvalZero      ignored internally by Kconfiglib, except when printing symbols.
4686*10465441SEvalZero
4687*10465441SEvalZero    filename/linenr:
4688*10465441SEvalZero      The location where the menu node appears. The filename is relative to
4689*10465441SEvalZero      $srctree (or to the current directory if $srctree isn't set), except
4690*10465441SEvalZero      absolute paths passed to 'source' and Kconfig.__init__() are preserved.
4691*10465441SEvalZero
4692*10465441SEvalZero    include_path:
4693*10465441SEvalZero      A tuple of (filename, linenr) tuples, giving the locations of the
4694*10465441SEvalZero      'source' statements via which the Kconfig file containing this menu node
4695*10465441SEvalZero      was included. The first element is the location of the 'source' statement
4696*10465441SEvalZero      in the top-level Kconfig file passed to Kconfig.__init__(), etc.
4697*10465441SEvalZero
4698*10465441SEvalZero      Note that the Kconfig file of the menu node itself isn't included. Check
4699*10465441SEvalZero      'filename' and 'linenr' for that.
4700*10465441SEvalZero
4701*10465441SEvalZero    kconfig:
4702*10465441SEvalZero      The Kconfig instance the menu node is from.
4703*10465441SEvalZero    """
4704*10465441SEvalZero    __slots__ = (
4705*10465441SEvalZero        "dep",
4706*10465441SEvalZero        "filename",
4707*10465441SEvalZero        "help",
4708*10465441SEvalZero        "include_path",
4709*10465441SEvalZero        "is_menuconfig",
4710*10465441SEvalZero        "item",
4711*10465441SEvalZero        "kconfig",
4712*10465441SEvalZero        "linenr",
4713*10465441SEvalZero        "list",
4714*10465441SEvalZero        "next",
4715*10465441SEvalZero        "parent",
4716*10465441SEvalZero        "prompt",
4717*10465441SEvalZero        "visibility",
4718*10465441SEvalZero
4719*10465441SEvalZero        # Properties
4720*10465441SEvalZero        "defaults",
4721*10465441SEvalZero        "selects",
4722*10465441SEvalZero        "implies",
4723*10465441SEvalZero        "ranges"
4724*10465441SEvalZero    )
4725*10465441SEvalZero
4726*10465441SEvalZero    def __init__(self):
4727*10465441SEvalZero        # Properties defined on this particular menu node. A local 'depends on'
4728*10465441SEvalZero        # only applies to these, in case a symbol is defined in multiple
4729*10465441SEvalZero        # locations.
4730*10465441SEvalZero        self.defaults = []
4731*10465441SEvalZero        self.selects = []
4732*10465441SEvalZero        self.implies = []
4733*10465441SEvalZero        self.ranges = []
4734*10465441SEvalZero
4735*10465441SEvalZero    @property
4736*10465441SEvalZero    def referenced(self):
4737*10465441SEvalZero        """
4738*10465441SEvalZero        See the class documentation.
4739*10465441SEvalZero        """
4740*10465441SEvalZero        # self.dep is included to catch dependencies from a lone 'depends on'
4741*10465441SEvalZero        # when there are no properties to propagate it to
4742*10465441SEvalZero        res = expr_items(self.dep)
4743*10465441SEvalZero
4744*10465441SEvalZero        if self.prompt:
4745*10465441SEvalZero            res |= expr_items(self.prompt[1])
4746*10465441SEvalZero
4747*10465441SEvalZero        if self.item is MENU:
4748*10465441SEvalZero            res |= expr_items(self.visibility)
4749*10465441SEvalZero
4750*10465441SEvalZero        for value, cond in self.defaults:
4751*10465441SEvalZero            res |= expr_items(value)
4752*10465441SEvalZero            res |= expr_items(cond)
4753*10465441SEvalZero
4754*10465441SEvalZero        for value, cond in self.selects:
4755*10465441SEvalZero            res.add(value)
4756*10465441SEvalZero            res |= expr_items(cond)
4757*10465441SEvalZero
4758*10465441SEvalZero        for value, cond in self.implies:
4759*10465441SEvalZero            res.add(value)
4760*10465441SEvalZero            res |= expr_items(cond)
4761*10465441SEvalZero
4762*10465441SEvalZero        for low, high, cond in self.ranges:
4763*10465441SEvalZero            res.add(low)
4764*10465441SEvalZero            res.add(high)
4765*10465441SEvalZero            res |= expr_items(cond)
4766*10465441SEvalZero
4767*10465441SEvalZero        return res
4768*10465441SEvalZero
4769*10465441SEvalZero    def __repr__(self):
4770*10465441SEvalZero        """
4771*10465441SEvalZero        Returns a string with information about the menu node when it is
4772*10465441SEvalZero        evaluated on e.g. the interactive Python prompt.
4773*10465441SEvalZero        """
4774*10465441SEvalZero        fields = []
4775*10465441SEvalZero
4776*10465441SEvalZero        if isinstance(self.item, Symbol):
4777*10465441SEvalZero            fields.append("menu node for symbol " + self.item.name)
4778*10465441SEvalZero
4779*10465441SEvalZero        elif isinstance(self.item, Choice):
4780*10465441SEvalZero            s = "menu node for choice"
4781*10465441SEvalZero            if self.item.name is not None:
4782*10465441SEvalZero                s += " " + self.item.name
4783*10465441SEvalZero            fields.append(s)
4784*10465441SEvalZero
4785*10465441SEvalZero        elif self.item is MENU:
4786*10465441SEvalZero            fields.append("menu node for menu")
4787*10465441SEvalZero
4788*10465441SEvalZero        elif self.item is COMMENT:
4789*10465441SEvalZero            fields.append("menu node for comment")
4790*10465441SEvalZero
4791*10465441SEvalZero        elif self.item is None:
4792*10465441SEvalZero            fields.append("menu node for if (should not appear in the final "
4793*10465441SEvalZero                          " tree)")
4794*10465441SEvalZero
4795*10465441SEvalZero        else:
4796*10465441SEvalZero            _internal_error("unable to determine type in MenuNode.__repr__()")
4797*10465441SEvalZero
4798*10465441SEvalZero        if self.prompt:
4799*10465441SEvalZero            fields.append('prompt "{}" (visibility {})'
4800*10465441SEvalZero                          .format(self.prompt[0],
4801*10465441SEvalZero                                  TRI_TO_STR[expr_value(self.prompt[1])]))
4802*10465441SEvalZero
4803*10465441SEvalZero        if isinstance(self.item, Symbol) and self.is_menuconfig:
4804*10465441SEvalZero            fields.append("is menuconfig")
4805*10465441SEvalZero
4806*10465441SEvalZero        fields.append("deps " + TRI_TO_STR[expr_value(self.dep)])
4807*10465441SEvalZero
4808*10465441SEvalZero        if self.item is MENU:
4809*10465441SEvalZero            fields.append("'visible if' deps " + \
4810*10465441SEvalZero                          TRI_TO_STR[expr_value(self.visibility)])
4811*10465441SEvalZero
4812*10465441SEvalZero        if isinstance(self.item, (Symbol, Choice)) and self.help is not None:
4813*10465441SEvalZero            fields.append("has help")
4814*10465441SEvalZero
4815*10465441SEvalZero        if self.list:
4816*10465441SEvalZero            fields.append("has child")
4817*10465441SEvalZero
4818*10465441SEvalZero        if self.next:
4819*10465441SEvalZero            fields.append("has next")
4820*10465441SEvalZero
4821*10465441SEvalZero        fields.append("{}:{}".format(self.filename, self.linenr))
4822*10465441SEvalZero
4823*10465441SEvalZero        return "<{}>".format(", ".join(fields))
4824*10465441SEvalZero
4825*10465441SEvalZero    def __str__(self):
4826*10465441SEvalZero        """
4827*10465441SEvalZero        Returns a string representation of the menu node, matching the Kconfig
4828*10465441SEvalZero        format.
4829*10465441SEvalZero
4830*10465441SEvalZero        The output could (almost) be fed back into a Kconfig parser to redefine
4831*10465441SEvalZero        the object associated with the menu node. See the module documentation
4832*10465441SEvalZero        for a gotcha related to choice symbols.
4833*10465441SEvalZero
4834*10465441SEvalZero        For symbols and choices with multiple menu nodes (multiple definition
4835*10465441SEvalZero        locations), properties that aren't associated with a particular menu
4836*10465441SEvalZero        node are shown on all menu nodes ('option env=...', 'optional' for
4837*10465441SEvalZero        choices, etc.).
4838*10465441SEvalZero        """
4839*10465441SEvalZero        return self.custom_str(standard_sc_expr_str)
4840*10465441SEvalZero
4841*10465441SEvalZero    def custom_str(self, sc_expr_str_fn):
4842*10465441SEvalZero        """
4843*10465441SEvalZero        Works like MenuNode.__str__(), but allows a custom format to be used
4844*10465441SEvalZero        for all symbol/choice references. See expr_str().
4845*10465441SEvalZero        """
4846*10465441SEvalZero        return self._menu_comment_node_str(sc_expr_str_fn) \
4847*10465441SEvalZero               if self.item in (MENU, COMMENT) else \
4848*10465441SEvalZero               self._sym_choice_node_str(sc_expr_str_fn)
4849*10465441SEvalZero
4850*10465441SEvalZero    def _menu_comment_node_str(self, sc_expr_str_fn):
4851*10465441SEvalZero        s = '{} "{}"\n'.format("menu" if self.item is MENU else "comment",
4852*10465441SEvalZero                               self.prompt[0])
4853*10465441SEvalZero
4854*10465441SEvalZero        if self.dep is not self.kconfig.y:
4855*10465441SEvalZero            s += "\tdepends on {}\n".format(expr_str(self.dep, sc_expr_str_fn))
4856*10465441SEvalZero
4857*10465441SEvalZero        if self.item is MENU and self.visibility is not self.kconfig.y:
4858*10465441SEvalZero            s += "\tvisible if {}\n".format(expr_str(self.visibility,
4859*10465441SEvalZero                                                     sc_expr_str_fn))
4860*10465441SEvalZero
4861*10465441SEvalZero        return s
4862*10465441SEvalZero
4863*10465441SEvalZero    def _sym_choice_node_str(self, sc_expr_str_fn):
4864*10465441SEvalZero        lines = []
4865*10465441SEvalZero
4866*10465441SEvalZero        def indent_add(s):
4867*10465441SEvalZero            lines.append("\t" + s)
4868*10465441SEvalZero
4869*10465441SEvalZero        def indent_add_cond(s, cond):
4870*10465441SEvalZero            if cond is not self.kconfig.y:
4871*10465441SEvalZero                s += " if " + expr_str(cond, sc_expr_str_fn)
4872*10465441SEvalZero            indent_add(s)
4873*10465441SEvalZero
4874*10465441SEvalZero        sc = self.item
4875*10465441SEvalZero
4876*10465441SEvalZero        if isinstance(sc, Symbol):
4877*10465441SEvalZero            lines.append(
4878*10465441SEvalZero                ("menuconfig " if self.is_menuconfig else "config ")
4879*10465441SEvalZero                + sc.name)
4880*10465441SEvalZero        else:
4881*10465441SEvalZero            lines.append("choice " + sc.name if sc.name else "choice")
4882*10465441SEvalZero
4883*10465441SEvalZero        if sc.orig_type is not UNKNOWN:
4884*10465441SEvalZero            indent_add(TYPE_TO_STR[sc.orig_type])
4885*10465441SEvalZero
4886*10465441SEvalZero        if self.prompt:
4887*10465441SEvalZero            indent_add_cond(
4888*10465441SEvalZero                'prompt "{}"'.format(escape(self.prompt[0])),
4889*10465441SEvalZero                self.prompt[1])
4890*10465441SEvalZero
4891*10465441SEvalZero        if isinstance(sc, Symbol):
4892*10465441SEvalZero            if sc.is_allnoconfig_y:
4893*10465441SEvalZero                indent_add("option allnoconfig_y")
4894*10465441SEvalZero
4895*10465441SEvalZero            if sc is sc.kconfig.defconfig_list:
4896*10465441SEvalZero                indent_add("option defconfig_list")
4897*10465441SEvalZero
4898*10465441SEvalZero            if sc.env_var is not None:
4899*10465441SEvalZero                indent_add('option env="{}"'.format(sc.env_var))
4900*10465441SEvalZero
4901*10465441SEvalZero            if sc is sc.kconfig.modules:
4902*10465441SEvalZero                indent_add("option modules")
4903*10465441SEvalZero
4904*10465441SEvalZero            for low, high, cond in self.ranges:
4905*10465441SEvalZero                indent_add_cond(
4906*10465441SEvalZero                    "range {} {}".format(sc_expr_str_fn(low),
4907*10465441SEvalZero                                         sc_expr_str_fn(high)),
4908*10465441SEvalZero                    cond)
4909*10465441SEvalZero
4910*10465441SEvalZero        for default, cond in self.defaults:
4911*10465441SEvalZero            indent_add_cond("default " + expr_str(default, sc_expr_str_fn),
4912*10465441SEvalZero                            cond)
4913*10465441SEvalZero
4914*10465441SEvalZero        if isinstance(sc, Choice) and sc.is_optional:
4915*10465441SEvalZero            indent_add("optional")
4916*10465441SEvalZero
4917*10465441SEvalZero        if isinstance(sc, Symbol):
4918*10465441SEvalZero            for select, cond in self.selects:
4919*10465441SEvalZero                indent_add_cond("select " + sc_expr_str_fn(select), cond)
4920*10465441SEvalZero
4921*10465441SEvalZero            for imply, cond in self.implies:
4922*10465441SEvalZero                indent_add_cond("imply " + sc_expr_str_fn(imply), cond)
4923*10465441SEvalZero
4924*10465441SEvalZero        if self.dep is not sc.kconfig.y:
4925*10465441SEvalZero            indent_add("depends on " + expr_str(self.dep, sc_expr_str_fn))
4926*10465441SEvalZero
4927*10465441SEvalZero        if self.help is not None:
4928*10465441SEvalZero            indent_add("help")
4929*10465441SEvalZero            for line in self.help.splitlines():
4930*10465441SEvalZero                indent_add("  " + line)
4931*10465441SEvalZero
4932*10465441SEvalZero        return "\n".join(lines) + "\n"
4933*10465441SEvalZero
4934*10465441SEvalZeroclass Variable(object):
4935*10465441SEvalZero    """
4936*10465441SEvalZero    Represents a preprocessor variable/function.
4937*10465441SEvalZero
4938*10465441SEvalZero    The following attributes are available:
4939*10465441SEvalZero
4940*10465441SEvalZero    name:
4941*10465441SEvalZero      The name of the variable.
4942*10465441SEvalZero
4943*10465441SEvalZero    value:
4944*10465441SEvalZero      The unexpanded value of the variable.
4945*10465441SEvalZero
4946*10465441SEvalZero    expanded_value:
4947*10465441SEvalZero      The expanded value of the variable. For simple variables (those defined
4948*10465441SEvalZero      with :=), this will equal 'value'. Accessing this property will raise a
4949*10465441SEvalZero      KconfigError if any variable in the expansion expands to itself.
4950*10465441SEvalZero
4951*10465441SEvalZero    is_recursive:
4952*10465441SEvalZero      True if the variable is recursive (defined with =).
4953*10465441SEvalZero    """
4954*10465441SEvalZero    __slots__ = (
4955*10465441SEvalZero        "_n_expansions",
4956*10465441SEvalZero        "is_recursive",
4957*10465441SEvalZero        "kconfig",
4958*10465441SEvalZero        "name",
4959*10465441SEvalZero        "value",
4960*10465441SEvalZero    )
4961*10465441SEvalZero
4962*10465441SEvalZero    @property
4963*10465441SEvalZero    def expanded_value(self):
4964*10465441SEvalZero        """
4965*10465441SEvalZero        See the class documentation.
4966*10465441SEvalZero        """
4967*10465441SEvalZero        return self.kconfig._expand_whole(self.value, ())
4968*10465441SEvalZero
4969*10465441SEvalZeroclass KconfigError(Exception):
4970*10465441SEvalZero    """
4971*10465441SEvalZero    Exception raised for Kconfig-related errors.
4972*10465441SEvalZero    """
4973*10465441SEvalZero
4974*10465441SEvalZero# Backwards compatibility
4975*10465441SEvalZeroKconfigSyntaxError = KconfigError
4976*10465441SEvalZero
4977*10465441SEvalZeroclass InternalError(Exception):
4978*10465441SEvalZero    """
4979*10465441SEvalZero    Exception raised for internal errors.
4980*10465441SEvalZero    """
4981*10465441SEvalZero
4982*10465441SEvalZero#
4983*10465441SEvalZero# Public functions
4984*10465441SEvalZero#
4985*10465441SEvalZero
4986*10465441SEvalZerodef expr_value(expr):
4987*10465441SEvalZero    """
4988*10465441SEvalZero    Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
4989*10465441SEvalZero    or 2 (y).
4990*10465441SEvalZero
4991*10465441SEvalZero    'expr' must be an already-parsed expression from a Symbol, Choice, or
4992*10465441SEvalZero    MenuNode property. To evaluate an expression represented as a string, use
4993*10465441SEvalZero    Kconfig.eval_string().
4994*10465441SEvalZero
4995*10465441SEvalZero    Passing subexpressions of expressions to this function works as expected.
4996*10465441SEvalZero    """
4997*10465441SEvalZero    if not isinstance(expr, tuple):
4998*10465441SEvalZero        return expr.tri_value
4999*10465441SEvalZero
5000*10465441SEvalZero    if expr[0] is AND:
5001*10465441SEvalZero        v1 = expr_value(expr[1])
5002*10465441SEvalZero        # Short-circuit the n case as an optimization (~5% faster
5003*10465441SEvalZero        # allnoconfig.py and allyesconfig.py, as of writing)
5004*10465441SEvalZero        return 0 if not v1 else min(v1, expr_value(expr[2]))
5005*10465441SEvalZero
5006*10465441SEvalZero    if expr[0] is OR:
5007*10465441SEvalZero        v1 = expr_value(expr[1])
5008*10465441SEvalZero        # Short-circuit the y case as an optimization
5009*10465441SEvalZero        return 2 if v1 == 2 else max(v1, expr_value(expr[2]))
5010*10465441SEvalZero
5011*10465441SEvalZero    if expr[0] is NOT:
5012*10465441SEvalZero        return 2 - expr_value(expr[1])
5013*10465441SEvalZero
5014*10465441SEvalZero    if expr[0] in _RELATIONS:
5015*10465441SEvalZero        # Implements <, <=, >, >= comparisons as well. These were added to
5016*10465441SEvalZero        # kconfig in 31847b67 (kconfig: allow use of relations other than
5017*10465441SEvalZero        # (in)equality).
5018*10465441SEvalZero
5019*10465441SEvalZero        oper, op1, op2 = expr
5020*10465441SEvalZero
5021*10465441SEvalZero        # If both operands are strings...
5022*10465441SEvalZero        if op1.orig_type is STRING and op2.orig_type is STRING:
5023*10465441SEvalZero            # ...then compare them lexicographically
5024*10465441SEvalZero            comp = _strcmp(op1.str_value, op2.str_value)
5025*10465441SEvalZero        else:
5026*10465441SEvalZero            # Otherwise, try to compare them as numbers
5027*10465441SEvalZero            try:
5028*10465441SEvalZero                comp = _sym_to_num(op1) - _sym_to_num(op2)
5029*10465441SEvalZero            except ValueError:
5030*10465441SEvalZero                # Fall back on a lexicographic comparison if the operands don't
5031*10465441SEvalZero                # parse as numbers
5032*10465441SEvalZero                comp = _strcmp(op1.str_value, op2.str_value)
5033*10465441SEvalZero
5034*10465441SEvalZero        if   oper is EQUAL:         res = comp == 0
5035*10465441SEvalZero        elif oper is UNEQUAL:       res = comp != 0
5036*10465441SEvalZero        elif oper is LESS:          res = comp < 0
5037*10465441SEvalZero        elif oper is LESS_EQUAL:    res = comp <= 0
5038*10465441SEvalZero        elif oper is GREATER:       res = comp > 0
5039*10465441SEvalZero        elif oper is GREATER_EQUAL: res = comp >= 0
5040*10465441SEvalZero
5041*10465441SEvalZero        return 2*res
5042*10465441SEvalZero
5043*10465441SEvalZero    _internal_error("Internal error while evaluating expression: "
5044*10465441SEvalZero                    "unknown operation {}.".format(expr[0]))
5045*10465441SEvalZero
5046*10465441SEvalZerodef standard_sc_expr_str(sc):
5047*10465441SEvalZero    """
5048*10465441SEvalZero    Standard symbol/choice printing function. Uses plain Kconfig syntax, and
5049*10465441SEvalZero    displays choices as <choice> (or <choice NAME>, for named choices).
5050*10465441SEvalZero
5051*10465441SEvalZero    See expr_str().
5052*10465441SEvalZero    """
5053*10465441SEvalZero    if isinstance(sc, Symbol):
5054*10465441SEvalZero        return '"{}"'.format(escape(sc.name)) if sc.is_constant else sc.name
5055*10465441SEvalZero
5056*10465441SEvalZero    # Choice
5057*10465441SEvalZero    return "<choice {}>".format(sc.name) if sc.name else "<choice>"
5058*10465441SEvalZero
5059*10465441SEvalZerodef expr_str(expr, sc_expr_str_fn=standard_sc_expr_str):
5060*10465441SEvalZero    """
5061*10465441SEvalZero    Returns the string representation of the expression 'expr', as in a Kconfig
5062*10465441SEvalZero    file.
5063*10465441SEvalZero
5064*10465441SEvalZero    Passing subexpressions of expressions to this function works as expected.
5065*10465441SEvalZero
5066*10465441SEvalZero    sc_expr_str_fn (default: standard_sc_expr_str):
5067*10465441SEvalZero      This function is called for every symbol/choice (hence "sc") appearing in
5068*10465441SEvalZero      the expression, with the symbol/choice as the argument. It is expected to
5069*10465441SEvalZero      return a string to be used for the symbol/choice.
5070*10465441SEvalZero
5071*10465441SEvalZero      This can be used e.g. to turn symbols/choices into links when generating
5072*10465441SEvalZero      documentation, or for printing the value of each symbol/choice after it.
5073*10465441SEvalZero
5074*10465441SEvalZero      Note that quoted values are represented as constants symbols
5075*10465441SEvalZero      (Symbol.is_constant == True).
5076*10465441SEvalZero    """
5077*10465441SEvalZero    if not isinstance(expr, tuple):
5078*10465441SEvalZero        return sc_expr_str_fn(expr)
5079*10465441SEvalZero
5080*10465441SEvalZero    if expr[0] is AND:
5081*10465441SEvalZero        return "{} && {}".format(_parenthesize(expr[1], OR, sc_expr_str_fn),
5082*10465441SEvalZero                                 _parenthesize(expr[2], OR, sc_expr_str_fn))
5083*10465441SEvalZero
5084*10465441SEvalZero    if expr[0] is OR:
5085*10465441SEvalZero        # This turns A && B || C && D into "(A && B) || (C && D)", which is
5086*10465441SEvalZero        # redundant, but more readable
5087*10465441SEvalZero        return "{} || {}".format(_parenthesize(expr[1], AND, sc_expr_str_fn),
5088*10465441SEvalZero                                 _parenthesize(expr[2], AND, sc_expr_str_fn))
5089*10465441SEvalZero
5090*10465441SEvalZero    if expr[0] is NOT:
5091*10465441SEvalZero        if isinstance(expr[1], tuple):
5092*10465441SEvalZero            return "!({})".format(expr_str(expr[1], sc_expr_str_fn))
5093*10465441SEvalZero        return "!" + sc_expr_str_fn(expr[1])  # Symbol
5094*10465441SEvalZero
5095*10465441SEvalZero    # Relation
5096*10465441SEvalZero    #
5097*10465441SEvalZero    # Relation operands are always symbols (quoted strings are constant
5098*10465441SEvalZero    # symbols)
5099*10465441SEvalZero    return "{} {} {}".format(sc_expr_str_fn(expr[1]), _REL_TO_STR[expr[0]],
5100*10465441SEvalZero                             sc_expr_str_fn(expr[2]))
5101*10465441SEvalZero
5102*10465441SEvalZerodef expr_items(expr):
5103*10465441SEvalZero    """
5104*10465441SEvalZero    Returns a set() of all items (symbols and choices) that appear in the
5105*10465441SEvalZero    expression 'expr'.
5106*10465441SEvalZero    """
5107*10465441SEvalZero
5108*10465441SEvalZero    res = set()
5109*10465441SEvalZero
5110*10465441SEvalZero    def rec(subexpr):
5111*10465441SEvalZero        if isinstance(subexpr, tuple):
5112*10465441SEvalZero            # AND, OR, NOT, or relation
5113*10465441SEvalZero
5114*10465441SEvalZero            rec(subexpr[1])
5115*10465441SEvalZero
5116*10465441SEvalZero            # NOTs only have a single operand
5117*10465441SEvalZero            if subexpr[0] is not NOT:
5118*10465441SEvalZero                rec(subexpr[2])
5119*10465441SEvalZero
5120*10465441SEvalZero        else:
5121*10465441SEvalZero            # Symbol or choice
5122*10465441SEvalZero            res.add(subexpr)
5123*10465441SEvalZero
5124*10465441SEvalZero    rec(expr)
5125*10465441SEvalZero    return res
5126*10465441SEvalZero
5127*10465441SEvalZerodef split_expr(expr, op):
5128*10465441SEvalZero    """
5129*10465441SEvalZero    Returns a list containing the top-level AND or OR operands in the
5130*10465441SEvalZero    expression 'expr', in the same (left-to-right) order as they appear in
5131*10465441SEvalZero    the expression.
5132*10465441SEvalZero
5133*10465441SEvalZero    This can be handy e.g. for splitting (weak) reverse dependencies
5134*10465441SEvalZero    from 'select' and 'imply' into individual selects/implies.
5135*10465441SEvalZero
5136*10465441SEvalZero    op:
5137*10465441SEvalZero      Either AND to get AND operands, or OR to get OR operands.
5138*10465441SEvalZero
5139*10465441SEvalZero      (Having this as an operand might be more future-safe than having two
5140*10465441SEvalZero      hardcoded functions.)
5141*10465441SEvalZero
5142*10465441SEvalZero
5143*10465441SEvalZero    Pseudo-code examples:
5144*10465441SEvalZero
5145*10465441SEvalZero      split_expr( A                    , OR  )  ->  [A]
5146*10465441SEvalZero      split_expr( A && B               , OR  )  ->  [A && B]
5147*10465441SEvalZero      split_expr( A || B               , OR  )  ->  [A, B]
5148*10465441SEvalZero      split_expr( A || B               , AND )  ->  [A || B]
5149*10465441SEvalZero      split_expr( A || B || (C && D)   , OR  )  ->  [A, B, C && D]
5150*10465441SEvalZero
5151*10465441SEvalZero      # Second || is not at the top level
5152*10465441SEvalZero      split_expr( A || (B && (C || D)) , OR )  ->  [A, B && (C || D)]
5153*10465441SEvalZero
5154*10465441SEvalZero      # Parentheses don't matter as long as we stay at the top level (don't
5155*10465441SEvalZero      # encounter any non-'op' nodes)
5156*10465441SEvalZero      split_expr( (A || B) || C        , OR )  ->  [A, B, C]
5157*10465441SEvalZero      split_expr( A || (B || C)        , OR )  ->  [A, B, C]
5158*10465441SEvalZero    """
5159*10465441SEvalZero    res = []
5160*10465441SEvalZero
5161*10465441SEvalZero    def rec(subexpr):
5162*10465441SEvalZero        if isinstance(subexpr, tuple) and subexpr[0] is op:
5163*10465441SEvalZero            rec(subexpr[1])
5164*10465441SEvalZero            rec(subexpr[2])
5165*10465441SEvalZero        else:
5166*10465441SEvalZero            res.append(subexpr)
5167*10465441SEvalZero
5168*10465441SEvalZero    rec(expr)
5169*10465441SEvalZero    return res
5170*10465441SEvalZero
5171*10465441SEvalZerodef escape(s):
5172*10465441SEvalZero    r"""
5173*10465441SEvalZero    Escapes the string 's' in the same fashion as is done for display in
5174*10465441SEvalZero    Kconfig format and when writing strings to a .config file. " and \ are
5175*10465441SEvalZero    replaced by \" and \\, respectively.
5176*10465441SEvalZero    """
5177*10465441SEvalZero    # \ must be escaped before " to avoid double escaping
5178*10465441SEvalZero    return s.replace("\\", r"\\").replace('"', r'\"')
5179*10465441SEvalZero
5180*10465441SEvalZero# unescape() helper
5181*10465441SEvalZero_unescape_sub = re.compile(r"\\(.)").sub
5182*10465441SEvalZero
5183*10465441SEvalZerodef unescape(s):
5184*10465441SEvalZero    r"""
5185*10465441SEvalZero    Unescapes the string 's'. \ followed by any character is replaced with just
5186*10465441SEvalZero    that character. Used internally when reading .config files.
5187*10465441SEvalZero    """
5188*10465441SEvalZero    return _unescape_sub(r"\1", s)
5189*10465441SEvalZero
5190*10465441SEvalZerodef standard_kconfig():
5191*10465441SEvalZero    """
5192*10465441SEvalZero    Helper for tools. Loads the top-level Kconfig specified as the first
5193*10465441SEvalZero    command-line argument, or "Kconfig" if there are no command-line arguments.
5194*10465441SEvalZero    Returns the Kconfig instance.
5195*10465441SEvalZero
5196*10465441SEvalZero    Exits with sys.exit() (which raises a SystemExit exception) and prints a
5197*10465441SEvalZero    usage note to stderr if more than one command-line argument is passed.
5198*10465441SEvalZero    """
5199*10465441SEvalZero    if len(sys.argv) > 2:
5200*10465441SEvalZero        sys.exit("usage: {} [Kconfig]".format(sys.argv[0]))
5201*10465441SEvalZero
5202*10465441SEvalZero    return Kconfig("Kconfig" if len(sys.argv) < 2 else sys.argv[1])
5203*10465441SEvalZero
5204*10465441SEvalZerodef standard_config_filename():
5205*10465441SEvalZero    """
5206*10465441SEvalZero    Helper for tools. Returns the value of KCONFIG_CONFIG (which specifies the
5207*10465441SEvalZero    .config file to load/save) if it is set, and ".config" otherwise.
5208*10465441SEvalZero    """
5209*10465441SEvalZero    return os.environ.get("KCONFIG_CONFIG", ".config")
5210*10465441SEvalZero
5211*10465441SEvalZero#
5212*10465441SEvalZero# Internal functions
5213*10465441SEvalZero#
5214*10465441SEvalZero
5215*10465441SEvalZerodef _visibility(sc):
5216*10465441SEvalZero    # Symbols and Choices have a "visibility" that acts as an upper bound on
5217*10465441SEvalZero    # the values a user can set for them, corresponding to the visibility in
5218*10465441SEvalZero    # e.g. 'make menuconfig'. This function calculates the visibility for the
5219*10465441SEvalZero    # Symbol or Choice 'sc' -- the logic is nearly identical.
5220*10465441SEvalZero
5221*10465441SEvalZero    vis = 0
5222*10465441SEvalZero
5223*10465441SEvalZero    for node in sc.nodes:
5224*10465441SEvalZero        if node.prompt:
5225*10465441SEvalZero            vis = max(vis, expr_value(node.prompt[1]))
5226*10465441SEvalZero
5227*10465441SEvalZero    if isinstance(sc, Symbol) and sc.choice:
5228*10465441SEvalZero        if sc.choice.orig_type is TRISTATE and \
5229*10465441SEvalZero           sc.orig_type is not TRISTATE and sc.choice.tri_value != 2:
5230*10465441SEvalZero            # Non-tristate choice symbols are only visible in y mode
5231*10465441SEvalZero            return 0
5232*10465441SEvalZero
5233*10465441SEvalZero        if sc.orig_type is TRISTATE and vis == 1 and sc.choice.tri_value == 2:
5234*10465441SEvalZero            # Choice symbols with m visibility are not visible in y mode
5235*10465441SEvalZero            return 0
5236*10465441SEvalZero
5237*10465441SEvalZero    # Promote m to y if we're dealing with a non-tristate (possibly due to
5238*10465441SEvalZero    # modules being disabled)
5239*10465441SEvalZero    if vis == 1 and sc.type is not TRISTATE:
5240*10465441SEvalZero        return 2
5241*10465441SEvalZero
5242*10465441SEvalZero    return vis
5243*10465441SEvalZero
5244*10465441SEvalZerodef _make_depend_on(sc, expr):
5245*10465441SEvalZero    # Adds 'sc' (symbol or choice) as a "dependee" to all symbols in 'expr'.
5246*10465441SEvalZero    # Constant symbols in 'expr' are skipped as they can never change value
5247*10465441SEvalZero    # anyway.
5248*10465441SEvalZero
5249*10465441SEvalZero    if isinstance(expr, tuple):
5250*10465441SEvalZero        # AND, OR, NOT, or relation
5251*10465441SEvalZero
5252*10465441SEvalZero        _make_depend_on(sc, expr[1])
5253*10465441SEvalZero
5254*10465441SEvalZero        # NOTs only have a single operand
5255*10465441SEvalZero        if expr[0] is not NOT:
5256*10465441SEvalZero            _make_depend_on(sc, expr[2])
5257*10465441SEvalZero
5258*10465441SEvalZero    elif not expr.is_constant:
5259*10465441SEvalZero        # Non-constant symbol, or choice
5260*10465441SEvalZero        expr._dependents.add(sc)
5261*10465441SEvalZero
5262*10465441SEvalZerodef _parenthesize(expr, type_, sc_expr_str_fn):
5263*10465441SEvalZero    # expr_str() helper. Adds parentheses around expressions of type 'type_'.
5264*10465441SEvalZero
5265*10465441SEvalZero    if isinstance(expr, tuple) and expr[0] is type_:
5266*10465441SEvalZero        return "({})".format(expr_str(expr, sc_expr_str_fn))
5267*10465441SEvalZero    return expr_str(expr, sc_expr_str_fn)
5268*10465441SEvalZero
5269*10465441SEvalZerodef _indentation(line):
5270*10465441SEvalZero    # Returns the length of the line's leading whitespace, treating tab stops
5271*10465441SEvalZero    # as being spaced 8 characters apart.
5272*10465441SEvalZero
5273*10465441SEvalZero    line = line.expandtabs()
5274*10465441SEvalZero    return len(line) - len(line.lstrip())
5275*10465441SEvalZero
5276*10465441SEvalZerodef _ordered_unique(lst):
5277*10465441SEvalZero    # Returns 'lst' with any duplicates removed, preserving order. This hacky
5278*10465441SEvalZero    # version seems to be a common idiom. It relies on short-circuit evaluation
5279*10465441SEvalZero    # and set.add() returning None, which is falsy.
5280*10465441SEvalZero
5281*10465441SEvalZero    seen = set()
5282*10465441SEvalZero    seen_add = seen.add
5283*10465441SEvalZero    return [x for x in lst if x not in seen and not seen_add(x)]
5284*10465441SEvalZero
5285*10465441SEvalZerodef _is_base_n(s, n):
5286*10465441SEvalZero    try:
5287*10465441SEvalZero        int(s, n)
5288*10465441SEvalZero        return True
5289*10465441SEvalZero    except ValueError:
5290*10465441SEvalZero        return False
5291*10465441SEvalZero
5292*10465441SEvalZerodef _strcmp(s1, s2):
5293*10465441SEvalZero    # strcmp()-alike that returns -1, 0, or 1
5294*10465441SEvalZero
5295*10465441SEvalZero    return (s1 > s2) - (s1 < s2)
5296*10465441SEvalZero
5297*10465441SEvalZerodef _is_num(s):
5298*10465441SEvalZero    # Returns True if the string 's' looks like a number.
5299*10465441SEvalZero    #
5300*10465441SEvalZero    # Internally, all operands in Kconfig are symbols, only undefined symbols
5301*10465441SEvalZero    # (which numbers usually are) get their name as their value.
5302*10465441SEvalZero    #
5303*10465441SEvalZero    # Only hex numbers that start with 0x/0X are classified as numbers.
5304*10465441SEvalZero    # Otherwise, symbols whose names happen to contain only the letters A-F
5305*10465441SEvalZero    # would trigger false positives.
5306*10465441SEvalZero
5307*10465441SEvalZero    try:
5308*10465441SEvalZero        int(s)
5309*10465441SEvalZero    except ValueError:
5310*10465441SEvalZero        if not s.startswith(("0x", "0X")):
5311*10465441SEvalZero            return False
5312*10465441SEvalZero
5313*10465441SEvalZero        try:
5314*10465441SEvalZero            int(s, 16)
5315*10465441SEvalZero        except ValueError:
5316*10465441SEvalZero            return False
5317*10465441SEvalZero
5318*10465441SEvalZero    return True
5319*10465441SEvalZero
5320*10465441SEvalZerodef _sym_to_num(sym):
5321*10465441SEvalZero    # expr_value() helper for converting a symbol to a number. Raises
5322*10465441SEvalZero    # ValueError for symbols that can't be converted.
5323*10465441SEvalZero
5324*10465441SEvalZero    # For BOOL and TRISTATE, n/m/y count as 0/1/2. This mirrors 9059a3493ef
5325*10465441SEvalZero    # ("kconfig: fix relational operators for bool and tristate symbols") in
5326*10465441SEvalZero    # the C implementation.
5327*10465441SEvalZero    return sym.tri_value if sym.orig_type in (BOOL, TRISTATE) else \
5328*10465441SEvalZero           int(sym.str_value, _TYPE_TO_BASE[sym.orig_type])
5329*10465441SEvalZero
5330*10465441SEvalZerodef _internal_error(msg):
5331*10465441SEvalZero    raise InternalError(
5332*10465441SEvalZero        msg +
5333*10465441SEvalZero        "\nSorry! You may want to send an email to ulfalizer a.t Google's "
5334*10465441SEvalZero        "email service to tell me about this. Include the message above and "
5335*10465441SEvalZero        "the stack trace and describe what you were doing.")
5336*10465441SEvalZero
5337*10465441SEvalZerodef _decoding_error(e, filename, macro_linenr=None):
5338*10465441SEvalZero    # Gives the filename and context for UnicodeDecodeError's, which are a pain
5339*10465441SEvalZero    # to debug otherwise. 'e' is the UnicodeDecodeError object.
5340*10465441SEvalZero    #
5341*10465441SEvalZero    # If the decoding error is for the output of a $(shell,...) command,
5342*10465441SEvalZero    # macro_linenr holds the line number where it was run (the exact line
5343*10465441SEvalZero    # number isn't available for decoding errors in files).
5344*10465441SEvalZero
5345*10465441SEvalZero    if macro_linenr is None:
5346*10465441SEvalZero        loc = filename
5347*10465441SEvalZero    else:
5348*10465441SEvalZero        loc = "output from macro at {}:{}".format(filename, macro_linenr)
5349*10465441SEvalZero
5350*10465441SEvalZero    raise KconfigError(
5351*10465441SEvalZero        "\n"
5352*10465441SEvalZero        "Malformed {} in {}\n"
5353*10465441SEvalZero        "Context: {}\n"
5354*10465441SEvalZero        "Problematic data: {}\n"
5355*10465441SEvalZero        "Reason: {}".format(
5356*10465441SEvalZero            e.encoding, loc,
5357*10465441SEvalZero            e.object[max(e.start - 40, 0):e.end + 40],
5358*10465441SEvalZero            e.object[e.start:e.end],
5359*10465441SEvalZero            e.reason))
5360*10465441SEvalZero
5361*10465441SEvalZerodef _name_and_loc(sc):
5362*10465441SEvalZero    # Helper for giving the symbol/choice name and location(s) in e.g. warnings
5363*10465441SEvalZero
5364*10465441SEvalZero    name = sc.name or "<choice>"
5365*10465441SEvalZero
5366*10465441SEvalZero    if not sc.nodes:
5367*10465441SEvalZero        return name + " (undefined)"
5368*10465441SEvalZero
5369*10465441SEvalZero    return "{} (defined at {})".format(
5370*10465441SEvalZero        name,
5371*10465441SEvalZero        ", ".join("{}:{}".format(node.filename, node.linenr)
5372*10465441SEvalZero                  for node in sc.nodes))
5373*10465441SEvalZero
5374*10465441SEvalZero
5375*10465441SEvalZero# Menu manipulation
5376*10465441SEvalZero
5377*10465441SEvalZerodef _expr_depends_on(expr, sym):
5378*10465441SEvalZero    # Reimplementation of expr_depends_symbol() from mconf.c. Used to determine
5379*10465441SEvalZero    # if a submenu should be implicitly created. This also influences which
5380*10465441SEvalZero    # items inside choice statements are considered choice items.
5381*10465441SEvalZero
5382*10465441SEvalZero    if not isinstance(expr, tuple):
5383*10465441SEvalZero        return expr is sym
5384*10465441SEvalZero
5385*10465441SEvalZero    if expr[0] in (EQUAL, UNEQUAL):
5386*10465441SEvalZero        # Check for one of the following:
5387*10465441SEvalZero        # sym = m/y, m/y = sym, sym != n, n != sym
5388*10465441SEvalZero
5389*10465441SEvalZero        left, right = expr[1:]
5390*10465441SEvalZero
5391*10465441SEvalZero        if right is sym:
5392*10465441SEvalZero            left, right = right, left
5393*10465441SEvalZero        elif left is not sym:
5394*10465441SEvalZero            return False
5395*10465441SEvalZero
5396*10465441SEvalZero        return (expr[0] is EQUAL and right is sym.kconfig.m or \
5397*10465441SEvalZero                                     right is sym.kconfig.y) or \
5398*10465441SEvalZero               (expr[0] is UNEQUAL and right is sym.kconfig.n)
5399*10465441SEvalZero
5400*10465441SEvalZero    return expr[0] is AND and \
5401*10465441SEvalZero           (_expr_depends_on(expr[1], sym) or
5402*10465441SEvalZero            _expr_depends_on(expr[2], sym))
5403*10465441SEvalZero
5404*10465441SEvalZerodef _auto_menu_dep(node1, node2):
5405*10465441SEvalZero    # Returns True if node2 has an "automatic menu dependency" on node1. If
5406*10465441SEvalZero    # node2 has a prompt, we check its condition. Otherwise, we look directly
5407*10465441SEvalZero    # at node2.dep.
5408*10465441SEvalZero
5409*10465441SEvalZero    # If node2 has no prompt, use its menu node dependencies instead
5410*10465441SEvalZero    return _expr_depends_on(node2.prompt[1] if node2.prompt else node2.dep,
5411*10465441SEvalZero                            node1.item)
5412*10465441SEvalZero
5413*10465441SEvalZerodef _flatten(node):
5414*10465441SEvalZero    # "Flattens" menu nodes without prompts (e.g. 'if' nodes and non-visible
5415*10465441SEvalZero    # symbols with children from automatic menu creation) so that their
5416*10465441SEvalZero    # children appear after them instead. This gives a clean menu structure
5417*10465441SEvalZero    # with no unexpected "jumps" in the indentation.
5418*10465441SEvalZero    #
5419*10465441SEvalZero    # Do not flatten promptless choices (which can appear "legitimitely" if a
5420*10465441SEvalZero    # named choice is defined in multiple locations to add on symbols). It
5421*10465441SEvalZero    # looks confusing, and the menuconfig already shows all choice symbols if
5422*10465441SEvalZero    # you enter the choice at some location with a prompt.
5423*10465441SEvalZero
5424*10465441SEvalZero    while node:
5425*10465441SEvalZero        if node.list and not node.prompt and \
5426*10465441SEvalZero           not isinstance(node.item, Choice):
5427*10465441SEvalZero
5428*10465441SEvalZero            last_node = node.list
5429*10465441SEvalZero            while 1:
5430*10465441SEvalZero                last_node.parent = node.parent
5431*10465441SEvalZero                if not last_node.next:
5432*10465441SEvalZero                    break
5433*10465441SEvalZero                last_node = last_node.next
5434*10465441SEvalZero
5435*10465441SEvalZero            last_node.next = node.next
5436*10465441SEvalZero            node.next = node.list
5437*10465441SEvalZero            node.list = None
5438*10465441SEvalZero
5439*10465441SEvalZero        node = node.next
5440*10465441SEvalZero
5441*10465441SEvalZerodef _remove_ifs(node):
5442*10465441SEvalZero    # Removes 'if' nodes (which can be recognized by MenuNode.item being None),
5443*10465441SEvalZero    # which are assumed to already have been flattened. The C implementation
5444*10465441SEvalZero    # doesn't bother to do this, but we expose the menu tree directly, and it
5445*10465441SEvalZero    # makes it nicer to work with.
5446*10465441SEvalZero
5447*10465441SEvalZero    first = node.list
5448*10465441SEvalZero    while first and first.item is None:
5449*10465441SEvalZero        first = first.next
5450*10465441SEvalZero
5451*10465441SEvalZero    cur = first
5452*10465441SEvalZero    while cur:
5453*10465441SEvalZero        if cur.next and cur.next.item is None:
5454*10465441SEvalZero            cur.next = cur.next.next
5455*10465441SEvalZero        cur = cur.next
5456*10465441SEvalZero
5457*10465441SEvalZero    node.list = first
5458*10465441SEvalZero
5459*10465441SEvalZerodef _finalize_choice(node):
5460*10465441SEvalZero    # Finalizes a choice, marking each symbol whose menu node has the choice as
5461*10465441SEvalZero    # the parent as a choice symbol, and automatically determining types if not
5462*10465441SEvalZero    # specified.
5463*10465441SEvalZero
5464*10465441SEvalZero    choice = node.item
5465*10465441SEvalZero
5466*10465441SEvalZero    cur = node.list
5467*10465441SEvalZero    while cur:
5468*10465441SEvalZero        if isinstance(cur.item, Symbol):
5469*10465441SEvalZero            cur.item.choice = choice
5470*10465441SEvalZero            choice.syms.append(cur.item)
5471*10465441SEvalZero        cur = cur.next
5472*10465441SEvalZero
5473*10465441SEvalZero    # If no type is specified for the choice, its type is that of
5474*10465441SEvalZero    # the first choice item with a specified type
5475*10465441SEvalZero    if choice.orig_type is UNKNOWN:
5476*10465441SEvalZero        for item in choice.syms:
5477*10465441SEvalZero            if item.orig_type is not UNKNOWN:
5478*10465441SEvalZero                choice.orig_type = item.orig_type
5479*10465441SEvalZero                break
5480*10465441SEvalZero
5481*10465441SEvalZero    # Each choice item of UNKNOWN type gets the type of the choice
5482*10465441SEvalZero    for sym in choice.syms:
5483*10465441SEvalZero        if sym.orig_type is UNKNOWN:
5484*10465441SEvalZero            sym.orig_type = choice.orig_type
5485*10465441SEvalZero
5486*10465441SEvalZerodef _check_dep_loop_sym(sym, ignore_choice):
5487*10465441SEvalZero    # Detects dependency loops using depth-first search on the dependency graph
5488*10465441SEvalZero    # (which is calculated earlier in Kconfig._build_dep()).
5489*10465441SEvalZero    #
5490*10465441SEvalZero    # Algorithm:
5491*10465441SEvalZero    #
5492*10465441SEvalZero    #  1. Symbols/choices start out with _visited = 0, meaning unvisited.
5493*10465441SEvalZero    #
5494*10465441SEvalZero    #  2. When a symbol/choice is first visited, _visited is set to 1, meaning
5495*10465441SEvalZero    #     "visited, potentially part of a dependency loop". The recursive
5496*10465441SEvalZero    #     search then continues from the symbol/choice.
5497*10465441SEvalZero    #
5498*10465441SEvalZero    #  3. If we run into a symbol/choice X with _visited already set to 1,
5499*10465441SEvalZero    #     there's a dependency loop. The loop is found on the call stack by
5500*10465441SEvalZero    #     recording symbols while returning ("on the way back") until X is seen
5501*10465441SEvalZero    #     again.
5502*10465441SEvalZero    #
5503*10465441SEvalZero    #  4. Once a symbol/choice and all its dependencies (or dependents in this
5504*10465441SEvalZero    #     case) have been checked recursively without detecting any loops, its
5505*10465441SEvalZero    #     _visited is set to 2, meaning "visited, not part of a dependency
5506*10465441SEvalZero    #     loop".
5507*10465441SEvalZero    #
5508*10465441SEvalZero    #     This saves work if we run into the symbol/choice again in later calls
5509*10465441SEvalZero    #     to _check_dep_loop_sym(). We just return immediately.
5510*10465441SEvalZero    #
5511*10465441SEvalZero    # Choices complicate things, as every choice symbol depends on every other
5512*10465441SEvalZero    # choice symbol in a sense. When a choice is "entered" via a choice symbol
5513*10465441SEvalZero    # X, we visit all choice symbols from the choice except X, and prevent
5514*10465441SEvalZero    # immediately revisiting the choice with a flag (ignore_choice).
5515*10465441SEvalZero    #
5516*10465441SEvalZero    # Maybe there's a better way to handle this (different flags or the
5517*10465441SEvalZero    # like...)
5518*10465441SEvalZero
5519*10465441SEvalZero    if not sym._visited:
5520*10465441SEvalZero        # sym._visited == 0, unvisited
5521*10465441SEvalZero
5522*10465441SEvalZero        sym._visited = 1
5523*10465441SEvalZero
5524*10465441SEvalZero        for dep in sym._dependents:
5525*10465441SEvalZero            # Choices show up in Symbol._dependents when the choice has the
5526*10465441SEvalZero            # symbol in a 'prompt' or 'default' condition (e.g.
5527*10465441SEvalZero            # 'default ... if SYM').
5528*10465441SEvalZero            #
5529*10465441SEvalZero            # Since we aren't entering the choice via a choice symbol, all
5530*10465441SEvalZero            # choice symbols need to be checked, hence the None.
5531*10465441SEvalZero            loop = _check_dep_loop_choice(dep, None) \
5532*10465441SEvalZero                   if isinstance(dep, Choice) \
5533*10465441SEvalZero                   else _check_dep_loop_sym(dep, False)
5534*10465441SEvalZero
5535*10465441SEvalZero            if loop:
5536*10465441SEvalZero                # Dependency loop found
5537*10465441SEvalZero                return _found_dep_loop(loop, sym)
5538*10465441SEvalZero
5539*10465441SEvalZero        if sym.choice and not ignore_choice:
5540*10465441SEvalZero            loop = _check_dep_loop_choice(sym.choice, sym)
5541*10465441SEvalZero            if loop:
5542*10465441SEvalZero                # Dependency loop found
5543*10465441SEvalZero                return _found_dep_loop(loop, sym)
5544*10465441SEvalZero
5545*10465441SEvalZero        # The symbol is not part of a dependency loop
5546*10465441SEvalZero        sym._visited = 2
5547*10465441SEvalZero
5548*10465441SEvalZero        # No dependency loop found
5549*10465441SEvalZero        return None
5550*10465441SEvalZero
5551*10465441SEvalZero    if sym._visited == 2:
5552*10465441SEvalZero        # The symbol was checked earlier and is already known to not be part of
5553*10465441SEvalZero        # a dependency loop
5554*10465441SEvalZero        return None
5555*10465441SEvalZero
5556*10465441SEvalZero    # sym._visited == 1, found a dependency loop. Return the symbol as the
5557*10465441SEvalZero    # first element in it.
5558*10465441SEvalZero    return (sym,)
5559*10465441SEvalZero
5560*10465441SEvalZerodef _check_dep_loop_choice(choice, skip):
5561*10465441SEvalZero    if not choice._visited:
5562*10465441SEvalZero        # choice._visited == 0, unvisited
5563*10465441SEvalZero
5564*10465441SEvalZero        choice._visited = 1
5565*10465441SEvalZero
5566*10465441SEvalZero        # Check for loops involving choice symbols. If we came here via a
5567*10465441SEvalZero        # choice symbol, skip that one, as we'd get a false positive
5568*10465441SEvalZero        # '<sym FOO> -> <choice> -> <sym FOO>' loop otherwise.
5569*10465441SEvalZero        for sym in choice.syms:
5570*10465441SEvalZero            if sym is not skip:
5571*10465441SEvalZero                # Prevent the choice from being immediately re-entered via the
5572*10465441SEvalZero                # "is a choice symbol" path by passing True
5573*10465441SEvalZero                loop = _check_dep_loop_sym(sym, True)
5574*10465441SEvalZero                if loop:
5575*10465441SEvalZero                    # Dependency loop found
5576*10465441SEvalZero                    return _found_dep_loop(loop, choice)
5577*10465441SEvalZero
5578*10465441SEvalZero        # The choice is not part of a dependency loop
5579*10465441SEvalZero        choice._visited = 2
5580*10465441SEvalZero
5581*10465441SEvalZero        # No dependency loop found
5582*10465441SEvalZero        return None
5583*10465441SEvalZero
5584*10465441SEvalZero    if choice._visited == 2:
5585*10465441SEvalZero        # The choice was checked earlier and is already known to not be part of
5586*10465441SEvalZero        # a dependency loop
5587*10465441SEvalZero        return None
5588*10465441SEvalZero
5589*10465441SEvalZero    # choice._visited == 1, found a dependency loop. Return the choice as the
5590*10465441SEvalZero    # first element in it.
5591*10465441SEvalZero    return (choice,)
5592*10465441SEvalZero
5593*10465441SEvalZerodef _found_dep_loop(loop, cur):
5594*10465441SEvalZero    # Called "on the way back" when we know we have a loop
5595*10465441SEvalZero
5596*10465441SEvalZero    # Is the symbol/choice 'cur' where the loop started?
5597*10465441SEvalZero    if cur is not loop[0]:
5598*10465441SEvalZero        # Nope, it's just a part of the loop
5599*10465441SEvalZero        return loop + (cur,)
5600*10465441SEvalZero
5601*10465441SEvalZero    # Yep, we have the entire loop. Throw an exception that shows it.
5602*10465441SEvalZero
5603*10465441SEvalZero    msg = "\nDependency loop\n" \
5604*10465441SEvalZero            "===============\n\n"
5605*10465441SEvalZero
5606*10465441SEvalZero    for item in loop:
5607*10465441SEvalZero        if item is not loop[0]:
5608*10465441SEvalZero            msg += "...depends on "
5609*10465441SEvalZero            if isinstance(item, Symbol) and item.choice:
5610*10465441SEvalZero                msg += "the choice symbol "
5611*10465441SEvalZero
5612*10465441SEvalZero        msg += "{}, with definition...\n\n{}\n" \
5613*10465441SEvalZero               .format(_name_and_loc(item), item)
5614*10465441SEvalZero
5615*10465441SEvalZero        # Small wart: Since we reuse the already calculated
5616*10465441SEvalZero        # Symbol/Choice._dependents sets for recursive dependency detection, we
5617*10465441SEvalZero        # lose information on whether a dependency came from a 'select'/'imply'
5618*10465441SEvalZero        # condition or e.g. a 'depends on'.
5619*10465441SEvalZero        #
5620*10465441SEvalZero        # This might cause selecting symbols to "disappear". For example,
5621*10465441SEvalZero        # a symbol B having 'select A if C' gives a direct dependency from A to
5622*10465441SEvalZero        # C, since it corresponds to a reverse dependency of B && C.
5623*10465441SEvalZero        #
5624*10465441SEvalZero        # Always print reverse dependencies for symbols that have them to make
5625*10465441SEvalZero        # sure information isn't lost. I wonder if there's some neat way to
5626*10465441SEvalZero        # improve this.
5627*10465441SEvalZero
5628*10465441SEvalZero        if isinstance(item, Symbol):
5629*10465441SEvalZero            if item.rev_dep is not item.kconfig.n:
5630*10465441SEvalZero                msg += "(select-related dependencies: {})\n\n" \
5631*10465441SEvalZero                       .format(expr_str(item.rev_dep))
5632*10465441SEvalZero
5633*10465441SEvalZero            if item.weak_rev_dep is not item.kconfig.n:
5634*10465441SEvalZero                msg += "(imply-related dependencies: {})\n\n" \
5635*10465441SEvalZero                       .format(expr_str(item.rev_dep))
5636*10465441SEvalZero
5637*10465441SEvalZero    msg += "...depends again on {}".format(_name_and_loc(loop[0]))
5638*10465441SEvalZero
5639*10465441SEvalZero    raise KconfigError(msg)
5640*10465441SEvalZero
5641*10465441SEvalZerodef _check_sym_sanity(sym):
5642*10465441SEvalZero    # Checks various symbol properties that are handiest to check after
5643*10465441SEvalZero    # parsing. Only generates errors and warnings.
5644*10465441SEvalZero
5645*10465441SEvalZero    if sym.orig_type in (BOOL, TRISTATE):
5646*10465441SEvalZero        # A helper function could be factored out here, but keep it
5647*10465441SEvalZero        # speedy/straightforward for now. bool/tristate symbols are by far the
5648*10465441SEvalZero        # most common, and most lack selects and implies.
5649*10465441SEvalZero
5650*10465441SEvalZero        for target_sym, _ in sym.selects:
5651*10465441SEvalZero            if target_sym.orig_type not in (BOOL, TRISTATE, UNKNOWN):
5652*10465441SEvalZero                sym.kconfig._warn("{} selects the {} symbol {}, which is not "
5653*10465441SEvalZero                                  "bool or tristate"
5654*10465441SEvalZero                                  .format(_name_and_loc(sym),
5655*10465441SEvalZero                                          TYPE_TO_STR[target_sym.orig_type],
5656*10465441SEvalZero                                          _name_and_loc(target_sym)))
5657*10465441SEvalZero
5658*10465441SEvalZero        for target_sym, _ in sym.implies:
5659*10465441SEvalZero            if target_sym.orig_type not in (BOOL, TRISTATE, UNKNOWN):
5660*10465441SEvalZero                sym.kconfig._warn("{} implies the {} symbol {}, which is not "
5661*10465441SEvalZero                                  "bool or tristate"
5662*10465441SEvalZero                                  .format(_name_and_loc(sym),
5663*10465441SEvalZero                                          TYPE_TO_STR[target_sym.orig_type],
5664*10465441SEvalZero                                          _name_and_loc(target_sym)))
5665*10465441SEvalZero
5666*10465441SEvalZero    elif sym.orig_type in (STRING, INT, HEX):
5667*10465441SEvalZero        for default, _ in sym.defaults:
5668*10465441SEvalZero            if not isinstance(default, Symbol):
5669*10465441SEvalZero                raise KconfigError(
5670*10465441SEvalZero                    "the {} symbol {} has a malformed default {} -- expected "
5671*10465441SEvalZero                    "a single symbol"
5672*10465441SEvalZero                    .format(TYPE_TO_STR[sym.orig_type], _name_and_loc(sym),
5673*10465441SEvalZero                            expr_str(default)))
5674*10465441SEvalZero
5675*10465441SEvalZero            if sym.orig_type is STRING:
5676*10465441SEvalZero                if not default.is_constant and not default.nodes and \
5677*10465441SEvalZero                   not default.name.isupper():
5678*10465441SEvalZero                    # 'default foo' on a string symbol could be either a symbol
5679*10465441SEvalZero                    # reference or someone leaving out the quotes. Guess that
5680*10465441SEvalZero                    # the quotes were left out if 'foo' isn't all-uppercase
5681*10465441SEvalZero                    # (and no symbol named 'foo' exists).
5682*10465441SEvalZero                    sym.kconfig._warn("style: quotes recommended around "
5683*10465441SEvalZero                                      "default value for string symbol "
5684*10465441SEvalZero                                      + _name_and_loc(sym))
5685*10465441SEvalZero
5686*10465441SEvalZero            elif sym.orig_type in (INT, HEX) and \
5687*10465441SEvalZero               not _int_hex_ok(default, sym.orig_type):
5688*10465441SEvalZero
5689*10465441SEvalZero                sym.kconfig._warn("the {0} symbol {1} has a non-{0} default {2}"
5690*10465441SEvalZero                                  .format(TYPE_TO_STR[sym.orig_type],
5691*10465441SEvalZero                                          _name_and_loc(sym),
5692*10465441SEvalZero                                          _name_and_loc(default)))
5693*10465441SEvalZero
5694*10465441SEvalZero        if sym.selects or sym.implies:
5695*10465441SEvalZero            sym.kconfig._warn("the {} symbol {} has selects or implies"
5696*10465441SEvalZero                              .format(TYPE_TO_STR[sym.orig_type],
5697*10465441SEvalZero                                      _name_and_loc(sym)))
5698*10465441SEvalZero
5699*10465441SEvalZero    else:  # UNKNOWN
5700*10465441SEvalZero        sym.kconfig._warn("{} defined without a type"
5701*10465441SEvalZero                          .format(_name_and_loc(sym)))
5702*10465441SEvalZero
5703*10465441SEvalZero
5704*10465441SEvalZero    if sym.ranges:
5705*10465441SEvalZero        if sym.orig_type not in (INT, HEX):
5706*10465441SEvalZero            sym.kconfig._warn(
5707*10465441SEvalZero                "the {} symbol {} has ranges, but is not int or hex"
5708*10465441SEvalZero                .format(TYPE_TO_STR[sym.orig_type], _name_and_loc(sym)))
5709*10465441SEvalZero        else:
5710*10465441SEvalZero            for low, high, _ in sym.ranges:
5711*10465441SEvalZero                if not _int_hex_ok(low, sym.orig_type) or \
5712*10465441SEvalZero                   not _int_hex_ok(high, sym.orig_type):
5713*10465441SEvalZero
5714*10465441SEvalZero                   sym.kconfig._warn("the {0} symbol {1} has a non-{0} range "
5715*10465441SEvalZero                                     "[{2}, {3}]"
5716*10465441SEvalZero                                     .format(TYPE_TO_STR[sym.orig_type],
5717*10465441SEvalZero                                             _name_and_loc(sym),
5718*10465441SEvalZero                                             _name_and_loc(low),
5719*10465441SEvalZero                                             _name_and_loc(high)))
5720*10465441SEvalZero
5721*10465441SEvalZero
5722*10465441SEvalZerodef _int_hex_ok(sym, type_):
5723*10465441SEvalZero    # Returns True if the (possibly constant) symbol 'sym' is valid as a value
5724*10465441SEvalZero    # for a symbol of type type_ (INT or HEX)
5725*10465441SEvalZero
5726*10465441SEvalZero    # 'not sym.nodes' implies a constant or undefined symbol, e.g. a plain
5727*10465441SEvalZero    # "123"
5728*10465441SEvalZero    if not sym.nodes:
5729*10465441SEvalZero        return _is_base_n(sym.name, _TYPE_TO_BASE[type_])
5730*10465441SEvalZero
5731*10465441SEvalZero    return sym.orig_type is type_
5732*10465441SEvalZero
5733*10465441SEvalZerodef _check_choice_sanity(choice):
5734*10465441SEvalZero    # Checks various choice properties that are handiest to check after
5735*10465441SEvalZero    # parsing. Only generates errors and warnings.
5736*10465441SEvalZero
5737*10465441SEvalZero    if choice.orig_type not in (BOOL, TRISTATE):
5738*10465441SEvalZero        choice.kconfig._warn("{} defined with type {}"
5739*10465441SEvalZero                             .format(_name_and_loc(choice),
5740*10465441SEvalZero                                     TYPE_TO_STR[choice.orig_type]))
5741*10465441SEvalZero
5742*10465441SEvalZero    for node in choice.nodes:
5743*10465441SEvalZero        if node.prompt:
5744*10465441SEvalZero            break
5745*10465441SEvalZero    else:
5746*10465441SEvalZero        choice.kconfig._warn(_name_and_loc(choice) +
5747*10465441SEvalZero                             " defined without a prompt")
5748*10465441SEvalZero
5749*10465441SEvalZero    for default, _ in choice.defaults:
5750*10465441SEvalZero        if not isinstance(default, Symbol):
5751*10465441SEvalZero            raise KconfigError(
5752*10465441SEvalZero                "{} has a malformed default {}"
5753*10465441SEvalZero                .format(_name_and_loc(choice), expr_str(default)))
5754*10465441SEvalZero
5755*10465441SEvalZero        if default.choice is not choice:
5756*10465441SEvalZero            choice.kconfig._warn("the default selection {} of {} is not "
5757*10465441SEvalZero                                 "contained in the choice"
5758*10465441SEvalZero                                 .format(_name_and_loc(default),
5759*10465441SEvalZero                                         _name_and_loc(choice)))
5760*10465441SEvalZero
5761*10465441SEvalZero    for sym in choice.syms:
5762*10465441SEvalZero        if sym.defaults:
5763*10465441SEvalZero            sym.kconfig._warn("default on the choice symbol {} will have "
5764*10465441SEvalZero                              "no effect".format(_name_and_loc(sym)))
5765*10465441SEvalZero
5766*10465441SEvalZero        if sym.rev_dep is not sym.kconfig.n:
5767*10465441SEvalZero            _warn_choice_select_imply(sym, sym.rev_dep, "selected")
5768*10465441SEvalZero
5769*10465441SEvalZero        if sym.weak_rev_dep is not sym.kconfig.n:
5770*10465441SEvalZero            _warn_choice_select_imply(sym, sym.weak_rev_dep, "implied")
5771*10465441SEvalZero
5772*10465441SEvalZero        for node in sym.nodes:
5773*10465441SEvalZero            if node.parent.item is choice:
5774*10465441SEvalZero                if not node.prompt:
5775*10465441SEvalZero                    sym.kconfig._warn("the choice symbol {} has no prompt"
5776*10465441SEvalZero                                      .format(_name_and_loc(sym)))
5777*10465441SEvalZero
5778*10465441SEvalZero            elif node.prompt:
5779*10465441SEvalZero                sym.kconfig._warn("the choice symbol {} is defined with a "
5780*10465441SEvalZero                                  "prompt outside the choice"
5781*10465441SEvalZero                                  .format(_name_and_loc(sym)))
5782*10465441SEvalZero
5783*10465441SEvalZerodef _warn_choice_select_imply(sym, expr, expr_type):
5784*10465441SEvalZero    msg = "the choice symbol {} is {} by the following symbols, which has " \
5785*10465441SEvalZero          "no effect: ".format(_name_and_loc(sym), expr_type)
5786*10465441SEvalZero
5787*10465441SEvalZero    # si = select/imply
5788*10465441SEvalZero    for si in split_expr(expr, OR):
5789*10465441SEvalZero        msg += "\n - " + _name_and_loc(split_expr(si, AND)[0])
5790*10465441SEvalZero
5791*10465441SEvalZero    sym.kconfig._warn(msg)
5792*10465441SEvalZero
5793*10465441SEvalZero
5794*10465441SEvalZero# Predefined preprocessor functions
5795*10465441SEvalZero
5796*10465441SEvalZerodef _filename_fn(kconf, args):
5797*10465441SEvalZero    return kconf._filename
5798*10465441SEvalZero
5799*10465441SEvalZerodef _lineno_fn(kconf, args):
5800*10465441SEvalZero    return str(kconf._linenr)
5801*10465441SEvalZero
5802*10465441SEvalZerodef _info_fn(kconf, args):
5803*10465441SEvalZero    print("{}:{}: {}".format(kconf._filename, kconf._linenr, args[1]))
5804*10465441SEvalZero
5805*10465441SEvalZero    return ""
5806*10465441SEvalZero
5807*10465441SEvalZerodef _warning_if_fn(kconf, args):
5808*10465441SEvalZero    if args[1] == "y":
5809*10465441SEvalZero        kconf._warn(args[2], kconf._filename, kconf._linenr)
5810*10465441SEvalZero
5811*10465441SEvalZero    return ""
5812*10465441SEvalZero
5813*10465441SEvalZerodef _error_if_fn(kconf, args):
5814*10465441SEvalZero    if args[1] == "y":
5815*10465441SEvalZero        raise KconfigError("{}:{}: {}".format(
5816*10465441SEvalZero            kconf._filename, kconf._linenr, args[2]))
5817*10465441SEvalZero
5818*10465441SEvalZero    return ""
5819*10465441SEvalZero
5820*10465441SEvalZerodef _shell_fn(kconf, args):
5821*10465441SEvalZero    stdout, stderr = subprocess.Popen(
5822*10465441SEvalZero        args[1], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
5823*10465441SEvalZero    ).communicate()
5824*10465441SEvalZero
5825*10465441SEvalZero    if not _IS_PY2:
5826*10465441SEvalZero        try:
5827*10465441SEvalZero            stdout = stdout.decode(kconf._encoding)
5828*10465441SEvalZero            stderr = stderr.decode(kconf._encoding)
5829*10465441SEvalZero        except UnicodeDecodeError as e:
5830*10465441SEvalZero            _decoding_error(e, kconf._filename, kconf._linenr)
5831*10465441SEvalZero
5832*10465441SEvalZero    if stderr:
5833*10465441SEvalZero        kconf._warn("'{}' wrote to stderr: {}".format(
5834*10465441SEvalZero                        args[1], "\n".join(stderr.splitlines())),
5835*10465441SEvalZero                    kconf._filename, kconf._linenr)
5836*10465441SEvalZero
5837*10465441SEvalZero    # Manual universal newlines with splitlines() (to prevent e.g. stray \r's
5838*10465441SEvalZero    # in command output on Windows), trailing newline removal, and
5839*10465441SEvalZero    # newline-to-space conversion.
5840*10465441SEvalZero    #
5841*10465441SEvalZero    # On Python 3 versions before 3.6, it's not possible to specify the
5842*10465441SEvalZero    # encoding when passing universal_newlines=True to Popen() (the 'encoding'
5843*10465441SEvalZero    # parameter was added in 3.6), so we do this manual version instead.
5844*10465441SEvalZero    return "\n".join(stdout.splitlines()).rstrip("\n").replace("\n", " ")
5845*10465441SEvalZero
5846*10465441SEvalZero
5847*10465441SEvalZero#
5848*10465441SEvalZero# Public global constants
5849*10465441SEvalZero#
5850*10465441SEvalZero
5851*10465441SEvalZero# Integers representing symbol types
5852*10465441SEvalZero(
5853*10465441SEvalZero    BOOL,
5854*10465441SEvalZero    HEX,
5855*10465441SEvalZero    INT,
5856*10465441SEvalZero    STRING,
5857*10465441SEvalZero    TRISTATE,
5858*10465441SEvalZero    UNKNOWN
5859*10465441SEvalZero) = range(6)
5860*10465441SEvalZero
5861*10465441SEvalZero# Integers representing menu and comment menu nodes
5862*10465441SEvalZero(
5863*10465441SEvalZero    MENU,
5864*10465441SEvalZero    COMMENT,
5865*10465441SEvalZero) = range(2)
5866*10465441SEvalZero
5867*10465441SEvalZero# Converts a symbol/choice type to a string
5868*10465441SEvalZeroTYPE_TO_STR = {
5869*10465441SEvalZero    UNKNOWN:  "unknown",
5870*10465441SEvalZero    BOOL:     "bool",
5871*10465441SEvalZero    TRISTATE: "tristate",
5872*10465441SEvalZero    STRING:   "string",
5873*10465441SEvalZero    HEX:      "hex",
5874*10465441SEvalZero    INT:      "int",
5875*10465441SEvalZero}
5876*10465441SEvalZero
5877*10465441SEvalZeroTRI_TO_STR = {
5878*10465441SEvalZero    0: "n",
5879*10465441SEvalZero    1: "m",
5880*10465441SEvalZero    2: "y",
5881*10465441SEvalZero}
5882*10465441SEvalZero
5883*10465441SEvalZeroSTR_TO_TRI = {
5884*10465441SEvalZero    "n": 0,
5885*10465441SEvalZero    "m": 1,
5886*10465441SEvalZero    "y": 2,
5887*10465441SEvalZero}
5888*10465441SEvalZero
5889*10465441SEvalZero#
5890*10465441SEvalZero# Internal global constants (plus public expression type
5891*10465441SEvalZero# constants)
5892*10465441SEvalZero#
5893*10465441SEvalZero
5894*10465441SEvalZero# Note:
5895*10465441SEvalZero#
5896*10465441SEvalZero# The token and type constants below are safe to test with 'is', which is a bit
5897*10465441SEvalZero# faster (~30% faster in a microbenchmark with Python 3 on my machine, and a
5898*10465441SEvalZero# few % faster for total parsing time), even without assuming Python's small
5899*10465441SEvalZero# integer optimization (which caches small integer objects). The constants end
5900*10465441SEvalZero# up pointing to unique integer objects, and since we consistently refer to
5901*10465441SEvalZero# them via the names below, we always get the same object.
5902*10465441SEvalZero#
5903*10465441SEvalZero# Client code would also need to use the names below, because the integer
5904*10465441SEvalZero# values can change e.g. when tokens get added. Client code would usually test
5905*10465441SEvalZero# with == too, which would be safe even in super obscure cases involving e.g.
5906*10465441SEvalZero# pickling (where 'is' would be a bad idea anyway) and no small-integer
5907*10465441SEvalZero# optimization.
5908*10465441SEvalZero
5909*10465441SEvalZero# Are we running on Python 2?
5910*10465441SEvalZero_IS_PY2 = sys.version_info[0] < 3
5911*10465441SEvalZero
5912*10465441SEvalZero# Tokens, with values 1, 2, ... . Avoiding 0 simplifies some checks by making
5913*10465441SEvalZero# all tokens except empty strings truthy.
5914*10465441SEvalZero(
5915*10465441SEvalZero    _T_ALLNOCONFIG_Y,
5916*10465441SEvalZero    _T_AND,
5917*10465441SEvalZero    _T_BOOL,
5918*10465441SEvalZero    _T_CHOICE,
5919*10465441SEvalZero    _T_CLOSE_PAREN,
5920*10465441SEvalZero    _T_COMMENT,
5921*10465441SEvalZero    _T_CONFIG,
5922*10465441SEvalZero    _T_DEFAULT,
5923*10465441SEvalZero    _T_DEFCONFIG_LIST,
5924*10465441SEvalZero    _T_DEF_BOOL,
5925*10465441SEvalZero    _T_DEF_HEX,
5926*10465441SEvalZero    _T_DEF_INT,
5927*10465441SEvalZero    _T_DEF_STRING,
5928*10465441SEvalZero    _T_DEF_TRISTATE,
5929*10465441SEvalZero    _T_DEPENDS,
5930*10465441SEvalZero    _T_ENDCHOICE,
5931*10465441SEvalZero    _T_ENDIF,
5932*10465441SEvalZero    _T_ENDMENU,
5933*10465441SEvalZero    _T_ENV,
5934*10465441SEvalZero    _T_EQUAL,
5935*10465441SEvalZero    _T_GREATER,
5936*10465441SEvalZero    _T_GREATER_EQUAL,
5937*10465441SEvalZero    _T_HELP,
5938*10465441SEvalZero    _T_HEX,
5939*10465441SEvalZero    _T_IF,
5940*10465441SEvalZero    _T_IMPLY,
5941*10465441SEvalZero    _T_INT,
5942*10465441SEvalZero    _T_LESS,
5943*10465441SEvalZero    _T_LESS_EQUAL,
5944*10465441SEvalZero    _T_MAINMENU,
5945*10465441SEvalZero    _T_MENU,
5946*10465441SEvalZero    _T_MENUCONFIG,
5947*10465441SEvalZero    _T_MODULES,
5948*10465441SEvalZero    _T_NOT,
5949*10465441SEvalZero    _T_ON,
5950*10465441SEvalZero    _T_OPEN_PAREN,
5951*10465441SEvalZero    _T_OPTION,
5952*10465441SEvalZero    _T_OPTIONAL,
5953*10465441SEvalZero    _T_OR,
5954*10465441SEvalZero    _T_ORSOURCE,
5955*10465441SEvalZero    _T_OSOURCE,
5956*10465441SEvalZero    _T_PROMPT,
5957*10465441SEvalZero    _T_RANGE,
5958*10465441SEvalZero    _T_RSOURCE,
5959*10465441SEvalZero    _T_SELECT,
5960*10465441SEvalZero    _T_SOURCE,
5961*10465441SEvalZero    _T_STRING,
5962*10465441SEvalZero    _T_TRISTATE,
5963*10465441SEvalZero    _T_UNEQUAL,
5964*10465441SEvalZero    _T_VISIBLE,
5965*10465441SEvalZero) = range(1, 51)
5966*10465441SEvalZero
5967*10465441SEvalZero# Public integers representing expression types
5968*10465441SEvalZero#
5969*10465441SEvalZero# Having these match the value of the corresponding tokens removes the need
5970*10465441SEvalZero# for conversion
5971*10465441SEvalZeroAND           = _T_AND
5972*10465441SEvalZeroOR            = _T_OR
5973*10465441SEvalZeroNOT           = _T_NOT
5974*10465441SEvalZeroEQUAL         = _T_EQUAL
5975*10465441SEvalZeroUNEQUAL       = _T_UNEQUAL
5976*10465441SEvalZeroLESS          = _T_LESS
5977*10465441SEvalZeroLESS_EQUAL    = _T_LESS_EQUAL
5978*10465441SEvalZeroGREATER       = _T_GREATER
5979*10465441SEvalZeroGREATER_EQUAL = _T_GREATER_EQUAL
5980*10465441SEvalZero
5981*10465441SEvalZero# Keyword to token map, with the get() method assigned directly as a small
5982*10465441SEvalZero# optimization
5983*10465441SEvalZero_get_keyword = {
5984*10465441SEvalZero    "---help---":     _T_HELP,
5985*10465441SEvalZero    "allnoconfig_y":  _T_ALLNOCONFIG_Y,
5986*10465441SEvalZero    "bool":           _T_BOOL,
5987*10465441SEvalZero    "boolean":        _T_BOOL,
5988*10465441SEvalZero    "choice":         _T_CHOICE,
5989*10465441SEvalZero    "comment":        _T_COMMENT,
5990*10465441SEvalZero    "config":         _T_CONFIG,
5991*10465441SEvalZero    "def_bool":       _T_DEF_BOOL,
5992*10465441SEvalZero    "def_hex":        _T_DEF_HEX,
5993*10465441SEvalZero    "def_int":        _T_DEF_INT,
5994*10465441SEvalZero    "def_string":     _T_DEF_STRING,
5995*10465441SEvalZero    "def_tristate":   _T_DEF_TRISTATE,
5996*10465441SEvalZero    "default":        _T_DEFAULT,
5997*10465441SEvalZero    "defconfig_list": _T_DEFCONFIG_LIST,
5998*10465441SEvalZero    "depends":        _T_DEPENDS,
5999*10465441SEvalZero    "endchoice":      _T_ENDCHOICE,
6000*10465441SEvalZero    "endif":          _T_ENDIF,
6001*10465441SEvalZero    "endmenu":        _T_ENDMENU,
6002*10465441SEvalZero    "env":            _T_ENV,
6003*10465441SEvalZero    "grsource":       _T_ORSOURCE,  # Backwards compatibility
6004*10465441SEvalZero    "gsource":        _T_OSOURCE,   # Backwards compatibility
6005*10465441SEvalZero    "help":           _T_HELP,
6006*10465441SEvalZero    "hex":            _T_HEX,
6007*10465441SEvalZero    "if":             _T_IF,
6008*10465441SEvalZero    "imply":          _T_IMPLY,
6009*10465441SEvalZero    "int":            _T_INT,
6010*10465441SEvalZero    "mainmenu":       _T_MAINMENU,
6011*10465441SEvalZero    "menu":           _T_MENU,
6012*10465441SEvalZero    "menuconfig":     _T_MENUCONFIG,
6013*10465441SEvalZero    "modules":        _T_MODULES,
6014*10465441SEvalZero    "on":             _T_ON,
6015*10465441SEvalZero    "option":         _T_OPTION,
6016*10465441SEvalZero    "optional":       _T_OPTIONAL,
6017*10465441SEvalZero    "orsource":       _T_ORSOURCE,
6018*10465441SEvalZero    "osource":        _T_OSOURCE,
6019*10465441SEvalZero    "prompt":         _T_PROMPT,
6020*10465441SEvalZero    "range":          _T_RANGE,
6021*10465441SEvalZero    "rsource":        _T_RSOURCE,
6022*10465441SEvalZero    "select":         _T_SELECT,
6023*10465441SEvalZero    "source":         _T_SOURCE,
6024*10465441SEvalZero    "string":         _T_STRING,
6025*10465441SEvalZero    "tristate":       _T_TRISTATE,
6026*10465441SEvalZero    "visible":        _T_VISIBLE,
6027*10465441SEvalZero}.get
6028*10465441SEvalZero
6029*10465441SEvalZero# Tokens after which strings are expected. This is used to tell strings from
6030*10465441SEvalZero# constant symbol references during tokenization, both of which are enclosed in
6031*10465441SEvalZero# quotes.
6032*10465441SEvalZero#
6033*10465441SEvalZero# Identifier-like lexemes ("missing quotes") are also treated as strings after
6034*10465441SEvalZero# these tokens. _T_CHOICE is included to avoid symbols being registered for
6035*10465441SEvalZero# named choices.
6036*10465441SEvalZero_STRING_LEX = frozenset((
6037*10465441SEvalZero    _T_BOOL,
6038*10465441SEvalZero    _T_CHOICE,
6039*10465441SEvalZero    _T_COMMENT,
6040*10465441SEvalZero    _T_HEX,
6041*10465441SEvalZero    _T_INT,
6042*10465441SEvalZero    _T_MAINMENU,
6043*10465441SEvalZero    _T_MENU,
6044*10465441SEvalZero    _T_ORSOURCE,
6045*10465441SEvalZero    _T_OSOURCE,
6046*10465441SEvalZero    _T_PROMPT,
6047*10465441SEvalZero    _T_RSOURCE,
6048*10465441SEvalZero    _T_SOURCE,
6049*10465441SEvalZero    _T_STRING,
6050*10465441SEvalZero    _T_TRISTATE,
6051*10465441SEvalZero))
6052*10465441SEvalZero
6053*10465441SEvalZero# Tokens for types, excluding def_bool, def_tristate, etc., for quick
6054*10465441SEvalZero# checks during parsing
6055*10465441SEvalZero_TYPE_TOKENS = frozenset((
6056*10465441SEvalZero    _T_BOOL,
6057*10465441SEvalZero    _T_TRISTATE,
6058*10465441SEvalZero    _T_INT,
6059*10465441SEvalZero    _T_HEX,
6060*10465441SEvalZero    _T_STRING,
6061*10465441SEvalZero))
6062*10465441SEvalZero
6063*10465441SEvalZero
6064*10465441SEvalZero# Helper functions for getting compiled regular expressions, with the needed
6065*10465441SEvalZero# matching function returned directly as a small optimization.
6066*10465441SEvalZero#
6067*10465441SEvalZero# Use ASCII regex matching on Python 3. It's already the default on Python 2.
6068*10465441SEvalZero
6069*10465441SEvalZerodef _re_match(regex):
6070*10465441SEvalZero    return re.compile(regex, 0 if _IS_PY2 else re.ASCII).match
6071*10465441SEvalZero
6072*10465441SEvalZerodef _re_search(regex):
6073*10465441SEvalZero    return re.compile(regex, 0 if _IS_PY2 else re.ASCII).search
6074*10465441SEvalZero
6075*10465441SEvalZero
6076*10465441SEvalZero# Various regular expressions used during parsing
6077*10465441SEvalZero
6078*10465441SEvalZero# The initial token on a line. Also eats leading and trailing whitespace, so
6079*10465441SEvalZero# that we can jump straight to the next token (or to the end of the line if
6080*10465441SEvalZero# there is only one token).
6081*10465441SEvalZero#
6082*10465441SEvalZero# This regex will also fail to match for empty lines and comment lines.
6083*10465441SEvalZero#
6084*10465441SEvalZero# '$' is included to detect a variable assignment left-hand side with a $ in it
6085*10465441SEvalZero# (which might be from a macro expansion).
6086*10465441SEvalZero_command_match = _re_match(r"\s*([$A-Za-z0-9_-]+)\s*")
6087*10465441SEvalZero
6088*10465441SEvalZero# An identifier/keyword after the first token. Also eats trailing whitespace.
6089*10465441SEvalZero_id_keyword_match = _re_match(r"([A-Za-z0-9_/.-]+)\s*")
6090*10465441SEvalZero
6091*10465441SEvalZero# A fragment in the left-hand side of a preprocessor variable assignment. These
6092*10465441SEvalZero# are the portions between macro expansions ($(foo)). Macros are supported in
6093*10465441SEvalZero# the LHS (variable name).
6094*10465441SEvalZero_assignment_lhs_fragment_match = _re_match("[A-Za-z0-9_-]*")
6095*10465441SEvalZero
6096*10465441SEvalZero# The assignment operator and value (right-hand side) in a preprocessor
6097*10465441SEvalZero# variable assignment
6098*10465441SEvalZero_assignment_rhs_match = _re_match(r"\s*(=|:=|\+=)\s*(.*)")
6099*10465441SEvalZero
6100*10465441SEvalZero# Special characters/strings while expanding a macro (')', ',', and '$(')
6101*10465441SEvalZero_macro_special_search = _re_search(r"\)|,|\$\(")
6102*10465441SEvalZero
6103*10465441SEvalZero# Special characters/strings while expanding a string (quotes, '\', and '$(')
6104*10465441SEvalZero_string_special_search = _re_search(r'"|\'|\\|\$\(')
6105*10465441SEvalZero
6106*10465441SEvalZero# A valid right-hand side for an assignment to a string symbol in a .config
6107*10465441SEvalZero# file, including escaped characters. Extracts the contents.
6108*10465441SEvalZero_conf_string_match = _re_match(r'"((?:[^\\"]|\\.)*)"')
6109*10465441SEvalZero
6110*10465441SEvalZero
6111*10465441SEvalZero# Token to type mapping
6112*10465441SEvalZero_TOKEN_TO_TYPE = {
6113*10465441SEvalZero    _T_BOOL:         BOOL,
6114*10465441SEvalZero    _T_DEF_BOOL:     BOOL,
6115*10465441SEvalZero    _T_DEF_HEX:      HEX,
6116*10465441SEvalZero    _T_DEF_INT:      INT,
6117*10465441SEvalZero    _T_DEF_STRING:   STRING,
6118*10465441SEvalZero    _T_DEF_TRISTATE: TRISTATE,
6119*10465441SEvalZero    _T_HEX:          HEX,
6120*10465441SEvalZero    _T_INT:          INT,
6121*10465441SEvalZero    _T_STRING:       STRING,
6122*10465441SEvalZero    _T_TRISTATE:     TRISTATE,
6123*10465441SEvalZero}
6124*10465441SEvalZero
6125*10465441SEvalZero# Constant representing that there's no cached choice selection. This is
6126*10465441SEvalZero# distinct from a cached None (no selection). We create a unique object (any
6127*10465441SEvalZero# will do) for it so we can test with 'is'.
6128*10465441SEvalZero_NO_CACHED_SELECTION = object()
6129*10465441SEvalZero
6130*10465441SEvalZero# Used in comparisons. 0 means the base is inferred from the format of the
6131*10465441SEvalZero# string.
6132*10465441SEvalZero_TYPE_TO_BASE = {
6133*10465441SEvalZero    HEX:      16,
6134*10465441SEvalZero    INT:      10,
6135*10465441SEvalZero    STRING:   0,
6136*10465441SEvalZero    UNKNOWN:  0,
6137*10465441SEvalZero}
6138*10465441SEvalZero
6139*10465441SEvalZero# Note: These constants deliberately equal the corresponding tokens (_T_EQUAL,
6140*10465441SEvalZero# _T_UNEQUAL, etc.), which removes the need for conversion
6141*10465441SEvalZero_RELATIONS = frozenset((
6142*10465441SEvalZero    EQUAL,
6143*10465441SEvalZero    UNEQUAL,
6144*10465441SEvalZero    LESS,
6145*10465441SEvalZero    LESS_EQUAL,
6146*10465441SEvalZero    GREATER,
6147*10465441SEvalZero    GREATER_EQUAL,
6148*10465441SEvalZero))
6149*10465441SEvalZero
6150*10465441SEvalZero_REL_TO_STR = {
6151*10465441SEvalZero    EQUAL:         "=",
6152*10465441SEvalZero    UNEQUAL:       "!=",
6153*10465441SEvalZero    LESS:          "<",
6154*10465441SEvalZero    LESS_EQUAL:    "<=",
6155*10465441SEvalZero    GREATER:       ">",
6156*10465441SEvalZero    GREATER_EQUAL: ">=",
6157*10465441SEvalZero}
6158*10465441SEvalZero
6159*10465441SEvalZero_INIT_SRCTREE_NOTE = """
6160*10465441SEvalZeroNOTE: Starting with Kconfiglib 10.0.0, the Kconfig filename passed to
6161*10465441SEvalZeroKconfig.__init__() is looked up relative to $srctree (which is set to '{}')
6162*10465441SEvalZeroinstead of relative to the working directory. Previously, $srctree only applied
6163*10465441SEvalZeroto files being source'd within Kconfig files. This change makes running scripts
6164*10465441SEvalZeroout-of-tree work seamlessly, with no special coding required. Sorry for the
6165*10465441SEvalZerobackwards compatibility break!
6166*10465441SEvalZero"""[1:]
6167