Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kconfiglib.py choice override of menuconfig bug #19069

Open
MrKevinWeiss opened this issue Dec 21, 2022 · 1 comment
Open

kconfiglib.py choice override of menuconfig bug #19069

MrKevinWeiss opened this issue Dec 21, 2022 · 1 comment
Labels
Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Comments

@MrKevinWeiss
Copy link
Contributor

Description

While trying to rework the USB dependencies I found an issue when using menuconfigs in named choice overrides in kconfigs menuconfig feature. The result is a crash when going back from the overridden (or additional) menuconfig from the named choice override.

Steps to reproduce the issue

To isolate the problem one can add the following file:

dist/tools/kconfiglib/Kconfig

config FILLER
    bool "FILLER"


menuconfig FOO
    bool "FOO"

if FOO


config FOOFILLER
    bool "FOOFILLER"

choice IMPLEMENTATION
    bool "IMPLEMENTATION prompt"

menuconfig U_BAZ
    bool "U_BAZ"

config U_BOOP
    bool "U_BOOP"
    depends on U_BAZ

menuconfig UU_BAZ
    bool "UU_BAZ"

config UU_BOOP
    bool "UU_BOOP"
    depends on UU_BAZ


endchoice

config FOOFILLER2
    bool "FOOFILLER2"

endif

choice IMPLEMENTATION

menuconfig BAZ
    bool "BAZ"

config BOOP
    bool "BOOP"
    depends on BAZ

endchoice

config FILLER2
    bool "FILLER2"

Running python menuconfig.py, navigate to the BAZ option so that the BOOP symbol is visible.
Exit out of the menu twice so that you see the FOO page.
Peek 2022-12-21 12-51

Expected results

For it to go back to the last selected item.

Actual results

an error resulting in:

Using default symbol values (no '.config')
Traceback (most recent call last):
  File "menuconfig.py", line 3289, in <module>
    _main()
  File "menuconfig.py", line 663, in _main
    menuconfig(standard_kconfig(__doc__))
  File "menuconfig.py", line 732, in menuconfig
    print(curses.wrapper(_menuconfig))
  File "/usr/lib/python3.8/curses/__init__.py", line 105, in wrapper
    return func(stdscr, *args, **kwds)
  File "menuconfig.py", line 891, in _menuconfig
    _leave_menu()
  File "menuconfig.py", line 1206, in _leave_menu
    _sel_node_i = _shown.index(_cur_menu)
ValueError: <menu node for choice IMPLEMENTATION, deps y, has child, has next, Kconfig:40> is not in list

Additional Notes

This is not the first time we saw an issue here, as this was open upstream due to this bug ulfalizer/Kconfiglib#94

However, it resets the context and does not keep the same position when going back.

Proposed Solution

The issue actually seems to stem from the creation of the kconfig tree. The parent of the overridden or additional menu does not have surrounding context. Looking deep I actually see the parent, in this case, going to the top menu as the dependencies are not propagated in that logic.

When the menuconfig tries to figure out the position it must be at when going back, it fails since the actual node object of the overridden named choice is not a part of the shown objects... Thus, trying to find the index fails.

By adding following snippet to kconfiglib.py I was able to give the overridden nodes a proper parent using the name of the named choice for matching...

            self._init(filename, warn, warn_to_stderr, encoding)
            # Add parents of stray named choices
            for choice in self.named_choices.values():
                parent = None
                for node in choice.nodes:
                    if node.prompt:
                        parent = node.parent
                        break
                for node in choice.nodes:
                    if not node.prompt:
                        node.parent = parent

This would require a bit more logic when looking this stuff up in menuconfig.py

    try:
        _sel_node_i = _shown.index(_cur_menu)
        _cur_menu = parent
    except ValueError:
        _sel_node_i = 0
        for node in _shown:
            if _cur_menu.item == node.item:
                break
            _sel_node_i += 1

Since the items match the in the list it works, it is just the the node objects that don't...

Probably there is a better way of handling this, likey something to do with only checking the items or improvements in the kconfiglib.py.

This seems to work for my use case but I can't help but wonder if

@MrKevinWeiss
Copy link
Contributor Author

ping @leandrolanzieri

@maribu maribu added the Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) label May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

No branches or pull requests

2 participants