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