menuconfig: Update to work around resizing crash on macOS
Update menuconfig (and kconfiglib and guiconfig, just to sync) to upstream revision 424d0d38e7, to get this commit in, which works around a crash on some macOS Python installations. menuconfig: Work around crash on resize on some macOS systems get_wch() has started raising curses.error when resizing the terminal on some macOS Python installations. Work around for now by falling back on getch(), which still works. See https://github.com/ulfalizer/Kconfiglib/issues/84. Needs more investigation, but I don't have a Mac handy. Based on https://github.com/ulfalizer/Kconfiglib/pull/85, but with some more comments. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
This commit is contained in:
parent
e04e4c27e8
commit
776de86dc7
3 changed files with 27 additions and 43 deletions
|
@ -1967,9 +1967,7 @@ def _sorted_sc_nodes(cached_nodes=[]):
|
||||||
key=lambda choice: choice.name or "")
|
key=lambda choice: choice.name or "")
|
||||||
|
|
||||||
cached_nodes += sorted(
|
cached_nodes += sorted(
|
||||||
[node
|
[node for choice in choices for node in choice.nodes],
|
||||||
for choice in choices
|
|
||||||
for node in choice.nodes],
|
|
||||||
key=lambda node: node.prompt[0] if node.prompt else "")
|
key=lambda node: node.prompt[0] if node.prompt else "")
|
||||||
|
|
||||||
return cached_nodes
|
return cached_nodes
|
||||||
|
|
|
@ -554,7 +554,7 @@ from glob import iglob
|
||||||
from os.path import dirname, exists, expandvars, islink, join, realpath
|
from os.path import dirname, exists, expandvars, islink, join, realpath
|
||||||
|
|
||||||
|
|
||||||
VERSION = (13, 5, 0)
|
VERSION = (13, 7, 1)
|
||||||
|
|
||||||
|
|
||||||
# File layout:
|
# File layout:
|
||||||
|
@ -947,7 +947,7 @@ class Kconfig(object):
|
||||||
self._init(filename, warn, warn_to_stderr, encoding)
|
self._init(filename, warn, warn_to_stderr, encoding)
|
||||||
except (EnvironmentError, KconfigError) as e:
|
except (EnvironmentError, KconfigError) as e:
|
||||||
if suppress_traceback:
|
if suppress_traceback:
|
||||||
cmd = sys.argv[0] # Empty string if missisng
|
cmd = sys.argv[0] # Empty string if missing
|
||||||
if cmd:
|
if cmd:
|
||||||
cmd += ": "
|
cmd += ": "
|
||||||
# Some long exception messages have extra newlines for better
|
# Some long exception messages have extra newlines for better
|
||||||
|
@ -1080,8 +1080,9 @@ class Kconfig(object):
|
||||||
self._readline = self._open(join(self.srctree, filename), "r").readline
|
self._readline = self._open(join(self.srctree, filename), "r").readline
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Parse the Kconfig files
|
# Parse the Kconfig files. Returns the last node, which we
|
||||||
self._parse_block(None, self.top_node, self.top_node)
|
# terminate with '.next = None'.
|
||||||
|
self._parse_block(None, self.top_node, self.top_node).next = None
|
||||||
self.top_node.list = self.top_node.next
|
self.top_node.list = self.top_node.next
|
||||||
self.top_node.next = None
|
self.top_node.next = None
|
||||||
except UnicodeDecodeError as e:
|
except UnicodeDecodeError as e:
|
||||||
|
@ -2894,7 +2895,7 @@ class Kconfig(object):
|
||||||
#
|
#
|
||||||
# prev:
|
# prev:
|
||||||
# The previous menu node. New nodes will be added after this one (by
|
# The previous menu node. New nodes will be added after this one (by
|
||||||
# modifying their 'next' pointer).
|
# modifying 'next' pointers).
|
||||||
#
|
#
|
||||||
# 'prev' is reused to parse a list of child menu nodes (for a menu or
|
# 'prev' is reused to parse a list of child menu nodes (for a menu or
|
||||||
# Choice): After parsing the children, the 'next' pointer is assigned
|
# Choice): After parsing the children, the 'next' pointer is assigned
|
||||||
|
@ -3086,17 +3087,16 @@ class Kconfig(object):
|
||||||
"no corresponding 'menu'" if t0 is _T_ENDMENU else
|
"no corresponding 'menu'" if t0 is _T_ENDMENU else
|
||||||
"unrecognized construct")
|
"unrecognized construct")
|
||||||
|
|
||||||
# End of file reached. Terminate the final node and return it.
|
# End of file reached. Return the last node.
|
||||||
|
|
||||||
if end_token:
|
if end_token:
|
||||||
raise KconfigError(
|
raise KconfigError(
|
||||||
"expected '{}' at end of '{}'"
|
"error: expected '{}' at end of '{}'"
|
||||||
.format("endchoice" if end_token is _T_ENDCHOICE else
|
.format("endchoice" if end_token is _T_ENDCHOICE else
|
||||||
"endif" if end_token is _T_ENDIF else
|
"endif" if end_token is _T_ENDIF else
|
||||||
"endmenu",
|
"endmenu",
|
||||||
self.filename))
|
self.filename))
|
||||||
|
|
||||||
prev.next = None
|
|
||||||
return prev
|
return prev
|
||||||
|
|
||||||
def _parse_cond(self):
|
def _parse_cond(self):
|
||||||
|
@ -6772,8 +6772,7 @@ def _error_if_fn(kconf, _, cond, msg):
|
||||||
|
|
||||||
|
|
||||||
def _shell_fn(kconf, _, command):
|
def _shell_fn(kconf, _, command):
|
||||||
# Only import as needed, to save some startup time
|
import subprocess # Only import as needed, to save some startup time
|
||||||
import subprocess
|
|
||||||
|
|
||||||
stdout, stderr = subprocess.Popen(
|
stdout, stderr = subprocess.Popen(
|
||||||
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
|
|
@ -319,10 +319,10 @@ _STYLES = {
|
||||||
|
|
||||||
# Blue-tinted style loosely resembling lxdialog
|
# Blue-tinted style loosely resembling lxdialog
|
||||||
"aquatic": """
|
"aquatic": """
|
||||||
path=fg:cyan,bg:blue,bold
|
path=fg:white,bg:blue
|
||||||
separator=fg:white,bg:cyan,bold
|
separator=fg:white,bg:cyan
|
||||||
help=path
|
help=path
|
||||||
frame=fg:white,bg:cyan,bold
|
frame=fg:white,bg:cyan
|
||||||
body=fg:white,bg:blue
|
body=fg:white,bg:blue
|
||||||
edit=fg:black,bg:white
|
edit=fg:black,bg:white
|
||||||
"""
|
"""
|
||||||
|
@ -1098,8 +1098,7 @@ def _enter_menu(menu):
|
||||||
global _menu_scroll
|
global _menu_scroll
|
||||||
|
|
||||||
if not menu.is_menuconfig:
|
if not menu.is_menuconfig:
|
||||||
# Not a menu
|
return False # Not a menu
|
||||||
return False
|
|
||||||
|
|
||||||
shown_sub = _shown_nodes(menu)
|
shown_sub = _shown_nodes(menu)
|
||||||
# Never enter empty menus. We depend on having a current node.
|
# Never enter empty menus. We depend on having a current node.
|
||||||
|
@ -1340,7 +1339,6 @@ def _draw_main():
|
||||||
|
|
||||||
term_width = _width(_stdscr)
|
term_width = _width(_stdscr)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update the separator row below the menu path
|
# Update the separator row below the menu path
|
||||||
#
|
#
|
||||||
|
@ -1387,7 +1385,6 @@ def _draw_main():
|
||||||
|
|
||||||
_menu_win.noutrefresh()
|
_menu_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update the bottom separator window
|
# Update the bottom separator window
|
||||||
#
|
#
|
||||||
|
@ -1412,7 +1409,6 @@ def _draw_main():
|
||||||
|
|
||||||
_bot_sep_win.noutrefresh()
|
_bot_sep_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update the help window, which shows either key bindings or help texts
|
# Update the help window, which shows either key bindings or help texts
|
||||||
#
|
#
|
||||||
|
@ -1433,7 +1429,6 @@ def _draw_main():
|
||||||
|
|
||||||
_help_win.noutrefresh()
|
_help_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update the top row with the menu path.
|
# Update the top row with the menu path.
|
||||||
#
|
#
|
||||||
|
@ -2293,7 +2288,6 @@ def _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,
|
||||||
|
|
||||||
edit_width = _width(edit_box) - 2
|
edit_width = _width(edit_box) - 2
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update list of matches
|
# Update list of matches
|
||||||
#
|
#
|
||||||
|
@ -2324,7 +2318,6 @@ def _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,
|
||||||
|
|
||||||
matches_win.noutrefresh()
|
matches_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update bottom separator line
|
# Update bottom separator line
|
||||||
#
|
#
|
||||||
|
@ -2337,7 +2330,6 @@ def _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,
|
||||||
|
|
||||||
bot_sep_win.noutrefresh()
|
bot_sep_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update help window at bottom
|
# Update help window at bottom
|
||||||
#
|
#
|
||||||
|
@ -2349,7 +2341,6 @@ def _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,
|
||||||
|
|
||||||
help_win.noutrefresh()
|
help_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update edit box. We do this last since it makes it handy to position the
|
# Update edit box. We do this last since it makes it handy to position the
|
||||||
# cursor.
|
# cursor.
|
||||||
|
@ -2439,12 +2430,10 @@ def _info_dialog(node, from_jump_to_dialog):
|
||||||
# Support starting a search from within the information dialog
|
# Support starting a search from within the information dialog
|
||||||
|
|
||||||
if from_jump_to_dialog:
|
if from_jump_to_dialog:
|
||||||
# Avoid recursion
|
return # Avoid recursion
|
||||||
return
|
|
||||||
|
|
||||||
if _jump_to_dialog():
|
if _jump_to_dialog():
|
||||||
# Jumped to a symbol. Cancel the information dialog.
|
return # Jumped to a symbol. Cancel the information dialog.
|
||||||
return
|
|
||||||
|
|
||||||
# Stay in the information dialog if the jump-to dialog was
|
# Stay in the information dialog if the jump-to dialog was
|
||||||
# canceled. Resize it in case the terminal was resized while the
|
# canceled. Resize it in case the terminal was resized while the
|
||||||
|
@ -2491,7 +2480,6 @@ def _draw_info_dialog(node, lines, scroll, top_line_win, text_win,
|
||||||
|
|
||||||
text_win_height, text_win_width = text_win.getmaxyx()
|
text_win_height, text_win_width = text_win.getmaxyx()
|
||||||
|
|
||||||
|
|
||||||
# Note: The top row is deliberately updated last. See _draw_main().
|
# Note: The top row is deliberately updated last. See _draw_main().
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2505,7 +2493,6 @@ def _draw_info_dialog(node, lines, scroll, top_line_win, text_win,
|
||||||
|
|
||||||
text_win.noutrefresh()
|
text_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update bottom separator line
|
# Update bottom separator line
|
||||||
#
|
#
|
||||||
|
@ -2518,7 +2505,6 @@ def _draw_info_dialog(node, lines, scroll, top_line_win, text_win,
|
||||||
|
|
||||||
bot_sep_win.noutrefresh()
|
bot_sep_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update help window at bottom
|
# Update help window at bottom
|
||||||
#
|
#
|
||||||
|
@ -2530,7 +2516,6 @@ def _draw_info_dialog(node, lines, scroll, top_line_win, text_win,
|
||||||
|
|
||||||
help_win.noutrefresh()
|
help_win.noutrefresh()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Update top row
|
# Update top row
|
||||||
#
|
#
|
||||||
|
@ -2589,8 +2574,7 @@ def _info_str(node):
|
||||||
_kconfig_def_info(choice)
|
_kconfig_def_info(choice)
|
||||||
)
|
)
|
||||||
|
|
||||||
# node.item in (MENU, COMMENT)
|
return _kconfig_def_info(node) # node.item in (MENU, COMMENT)
|
||||||
return _kconfig_def_info(node)
|
|
||||||
|
|
||||||
|
|
||||||
def _name_info(sc):
|
def _name_info(sc):
|
||||||
|
@ -2947,7 +2931,6 @@ def _edit_text(c, s, i, hscroll, width):
|
||||||
max_scroll = max(len(s) - width + 1, 0)
|
max_scroll = max(len(s) - width + 1, 0)
|
||||||
hscroll = min(i - width + _SCROLL_OFFSET + 1, max_scroll)
|
hscroll = min(i - width + _SCROLL_OFFSET + 1, max_scroll)
|
||||||
|
|
||||||
|
|
||||||
return s, i, hscroll
|
return s, i, hscroll
|
||||||
|
|
||||||
|
|
||||||
|
@ -3097,8 +3080,7 @@ def _check_valid(sym, s):
|
||||||
# Otherwise, displays an error and returns False.
|
# Otherwise, displays an error and returns False.
|
||||||
|
|
||||||
if sym.orig_type not in (INT, HEX):
|
if sym.orig_type not in (INT, HEX):
|
||||||
# Anything goes for non-int/hex symbols
|
return True # Anything goes for non-int/hex symbols
|
||||||
return True
|
|
||||||
|
|
||||||
base = 10 if sym.orig_type == INT else 16
|
base = 10 if sym.orig_type == INT else 16
|
||||||
try:
|
try:
|
||||||
|
@ -3155,12 +3137,17 @@ def _is_num(name):
|
||||||
|
|
||||||
|
|
||||||
def _getch_compat(win):
|
def _getch_compat(win):
|
||||||
# Uses get_wch() if available (Python 3.3+) and getch() otherwise. Also
|
# Uses get_wch() if available (Python 3.3+) and getch() otherwise.
|
||||||
# handles a PDCurses resizing quirk.
|
#
|
||||||
|
# Also falls back on getch() if get_wch() raises curses.error, to work
|
||||||
|
# around an issue when resizing the terminal on at least macOS Catalina.
|
||||||
|
# See https://github.com/ulfalizer/Kconfiglib/issues/84.
|
||||||
|
#
|
||||||
|
# Also handles a PDCurses resizing quirk.
|
||||||
|
|
||||||
if hasattr(win, "get_wch"):
|
try:
|
||||||
c = win.get_wch()
|
c = win.get_wch()
|
||||||
else:
|
except (AttributeError, curses.error):
|
||||||
c = win.getch()
|
c = win.getch()
|
||||||
if 0 <= c <= 255:
|
if 0 <= c <= 255:
|
||||||
c = chr(c)
|
c = chr(c)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue