diff --git a/lib/wificom/punchbag.py b/lib/wificom/punchbag.py index 2faf2ef..84b6a55 100644 --- a/lib/wificom/punchbag.py +++ b/lib/wificom/punchbag.py @@ -3,21 +3,26 @@ Handles the DigiROM tree. ''' +NO_CONTENT = -1 +LEADING_SPACE = -2 + def count_tabs(line): ''' - Count leading tabs on line. None for comment or no content. + Count leading tabs on line. + NO_CONTENT for comment, blank line, or tabs only. + LEADING_SPACE if a space was found before text begins. ''' tabs = 0 for character in line: if character == "\t": tabs += 1 elif character in "#\r\n": - return None + return NO_CONTENT elif character == " ": - raise ValueError("Tabs are required") + return LEADING_SPACE else: return tabs - return None + return NO_CONTENT class DigiROM_Node: #pylint:disable=invalid-name ''' @@ -52,9 +57,9 @@ def children(self): f.seek(pos) f.readline() prev_tabs = start_tabs - tabs = None + tabs = NO_CONTENT while True: - if tabs is not None: + if tabs != NO_CONTENT: prev_tabs = tabs pos = f.tell() line = f.readline() @@ -62,13 +67,15 @@ def children(self): # EOF break tabs = count_tabs(line) - if tabs is None: + if tabs == LEADING_SPACE: + self._error("Tabs required", pos) + if tabs == NO_CONTENT: continue if tabs <= start_tabs: break tab_step = tabs - prev_tabs if tab_step == 0 or tab_step > 1: - raise ValueError("Layout error") + self._error("Layout error", pos) if tabs == start_tabs + 1: result.append(DigiROM_Node(line.strip(), pos)) elif tab_step == 1: @@ -93,9 +100,17 @@ def digirom(self, node): def pick(self, node): '''Move to the menu option at the chosen node.''' if node.leaf_pos is not None: - raise ValueError("No menu here") + self._error("No menu here", node.pos) self._menu_path.append(node.pos) def back(self): '''Step back one menu level. Ignored if at the root.''' if len(self._menu_path) > 0: self._menu_path.pop() + def _error(self, message, pos): + '''Raise ValueError with start-of-line seek position converted to line number.''' + f = self._file_obj + f.seek(0) + line_number = 0 + while f.tell() <= pos and f.readline() != "": + line_number += 1 + raise ValueError(f"L{line_number}: {message}")