@@ -214,6 +214,67 @@ def format_rest_text(text, indent):
214
214
return text
215
215
216
216
217
+ def _minimize_expr (expr , visibility ):
218
+ def expr_nodes_invisible (e ):
219
+ return hasattr (e , 'nodes' ) and len (e .nodes ) > 0 and all (not visibility .visible (i ) for i in e .nodes )
220
+
221
+ if isinstance (expr , tuple ):
222
+ if expr [0 ] == kconfiglib .NOT :
223
+ new_expr = _minimize_expr (expr [1 ], visibility )
224
+ return kconfiglib .Kconfig .y if new_expr == kconfiglib .Kconfig .n else new_expr
225
+ else :
226
+ new_expr1 = _minimize_expr (expr [1 ], visibility )
227
+ new_expr2 = _minimize_expr (expr [2 ], visibility )
228
+ if expr [0 ] == kconfiglib .AND :
229
+ if new_expr1 == kconfiglib .Kconfig .n or new_expr2 == kconfiglib .Kconfig .n :
230
+ return kconfiglib .Kconfig .n
231
+ if new_expr1 == kconfiglib .Kconfig .y :
232
+ return new_expr2
233
+ if new_expr2 == kconfiglib .Kconfig .y :
234
+ return new_expr1
235
+ elif expr [0 ] == kconfiglib .OR :
236
+ if new_expr1 == kconfiglib .Kconfig .y or new_expr2 == kconfiglib .Kconfig .y :
237
+ return kconfiglib .Kconfig .y
238
+ if new_expr1 == kconfiglib .Kconfig .n :
239
+ return new_expr2
240
+ if new_expr2 == kconfiglib .Kconfig .n :
241
+ return new_expr1
242
+ elif expr [0 ] == kconfiglib .EQUAL :
243
+ if not isinstance (new_expr1 , type (new_expr2 )):
244
+ return kconfiglib .Kconfig .n
245
+ if new_expr1 == new_expr2 :
246
+ return kconfiglib .Kconfig .y
247
+ elif expr [0 ] == kconfiglib .UNEQUAL :
248
+ if not isinstance (new_expr1 , type (new_expr2 )):
249
+ return kconfiglib .Kconfig .y
250
+ if new_expr1 != new_expr2 :
251
+ return kconfiglib .Kconfig .n
252
+ else : # <, <=, >, >=
253
+ if not isinstance (new_expr1 , type (new_expr2 )):
254
+ return kconfiglib .Kconfig .n # e.g "True < 2"
255
+
256
+ if expr_nodes_invisible (new_expr1 ) or expr_nodes_invisible (new_expr2 ):
257
+ return kconfiglib .Kconfig .y if kconfiglib .expr_value (expr ) else kconfiglib .Kconfig .n
258
+
259
+ return (expr [0 ], new_expr1 , new_expr2 )
260
+
261
+ if (not kconfiglib .expr_value (expr ) and len (expr .config_string ) == 0 and expr_nodes_invisible (expr )):
262
+ # nodes which are invisible
263
+ # len(expr.nodes) > 0 avoids constant symbols without actual node definitions, e.g. integer constants
264
+ # len(expr.config_string) == 0 avoids hidden configs which reflects the values of choices
265
+ return kconfiglib .Kconfig .n
266
+
267
+ if (kconfiglib .expr_value (expr ) and len (expr .config_string ) > 0 and expr_nodes_invisible (expr )):
268
+ # hidden config dependencies which will be written to sdkconfig as enabled ones.
269
+ return kconfiglib .Kconfig .y
270
+
271
+ if any (node .item .name .startswith (visibility .target_env_var ) for node in expr .nodes ):
272
+ # We know the actual values for IDF_TARGETs
273
+ return kconfiglib .Kconfig .y if kconfiglib .expr_value (expr ) else kconfiglib .Kconfig .n
274
+
275
+ return expr
276
+
277
+
217
278
def write_menu_item (f , node , visibility ):
218
279
def is_choice (node ):
219
280
""" Skip choice nodes, they are handled as part of the parent (see below) """
@@ -269,6 +330,56 @@ def is_choice(node):
269
330
270
331
f .write ('\n \n ' )
271
332
333
+ if isinstance (node .item , kconfiglib .Symbol ):
334
+ def _expr_str (sc ):
335
+ if sc .is_constant or not sc .nodes or sc .choice :
336
+ return '{}' .format (sc .name )
337
+ return ':ref:`%s%s`' % (sc .kconfig .config_prefix , sc .name )
338
+
339
+ range_strs = []
340
+ for low , high , cond in node .item .ranges :
341
+ cond = _minimize_expr (cond , visibility )
342
+ if cond == kconfiglib .Kconfig .n :
343
+ continue
344
+ if not isinstance (cond , tuple ) and cond != kconfiglib .Kconfig .y :
345
+ if len (cond .nodes ) > 0 and all (not visibility .visible (i ) for i in cond .nodes ):
346
+ if not kconfiglib .expr_value (cond ):
347
+ continue
348
+ range_str = '%s- from %s to %s' % (INDENT * 2 , low .str_value , high .str_value )
349
+ if cond != kconfiglib .Kconfig .y and not kconfiglib .expr_value (cond ):
350
+ range_str += ' if %s' % kconfiglib .expr_str (cond , _expr_str )
351
+ range_strs .append (range_str )
352
+ if len (range_strs ) > 0 :
353
+ f .write ('%sRange:\n ' % INDENT )
354
+ f .write ('\n ' .join (range_strs ))
355
+ f .write ('\n \n ' )
356
+
357
+ default_strs = []
358
+ for default , cond in node .item .defaults :
359
+ cond = _minimize_expr (cond , visibility )
360
+ if cond == kconfiglib .Kconfig .n :
361
+ continue
362
+ if not isinstance (cond , tuple ) and cond != kconfiglib .Kconfig .y :
363
+ if len (cond .nodes ) > 0 and all (not visibility .visible (i ) for i in cond .nodes ):
364
+ if not kconfiglib .expr_value (cond ):
365
+ continue
366
+ # default.type is mostly UNKNOWN so it cannot be used reliably for detecting the type
367
+ d = default .str_value
368
+ if d in ['y' , 'Y' ]:
369
+ d = 'Yes (enabled)'
370
+ elif d in ['n' , 'N' ]:
371
+ d = 'No (disabled)'
372
+ elif re .search (r'[^0-9a-fA-F]' , d ): # simple string detection: if it not a valid number
373
+ d = '"%s"' % d
374
+ default_str = '%s- %s' % (INDENT * 2 , d )
375
+ if cond != kconfiglib .Kconfig .y and not kconfiglib .expr_value (cond ):
376
+ default_str += ' if %s' % kconfiglib .expr_str (cond , _expr_str )
377
+ default_strs .append (default_str )
378
+ if len (default_strs ) > 0 :
379
+ f .write ('%sDefault value:\n ' % INDENT )
380
+ f .write ('\n ' .join (default_strs ))
381
+ f .write ('\n \n ' )
382
+
272
383
if is_menu :
273
384
# enumerate links to child items
274
385
child_list = []
0 commit comments