1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-07-15 01:24:29 +02:00

possible fix for infinite loop issue

This commit is contained in:
Kelly Brazil
2023-12-09 16:14:27 -08:00
parent 47c7e081f3
commit 2630049ab7
2 changed files with 39 additions and 2 deletions

View File

@ -193,7 +193,7 @@ from jc.parsers.pyedid.helpers.edid_helper import EdidHelper
class info: class info:
"""Provides parser metadata (version, author, etc.)""" """Provides parser metadata (version, author, etc.)"""
version = "1.3" version = "1.4"
description = "`xrandr` command parser" description = "`xrandr` command parser"
author = "Kevin Lyter" author = "Kevin Lyter"
author_email = "code (at) lyterk.com" author_email = "code (at) lyterk.com"
@ -205,6 +205,25 @@ class info:
__version__ = info.version __version__ = info.version
# keep parsing state so we know which parsers have already tried the line
parse_state: Dict[str, List] = {}
def _was_parsed(line: str, parser: str) -> bool:
"""
Check if entered parser has already parsed. If so return True.
If not, return false and add the parser to the list for the line entry.
"""
if line in parse_state:
if parser in parse_state[line]:
return True
parse_state[line].append(parser)
return False
parse_state[line] = [parser]
return False
try: try:
from typing import TypedDict from typing import TypedDict
@ -291,6 +310,10 @@ _screen_pattern = (
def _parse_screen(next_lines: List[str]) -> Optional[Screen]: def _parse_screen(next_lines: List[str]) -> Optional[Screen]:
next_line = next_lines.pop() next_line = next_lines.pop()
if _was_parsed(next_line, 'screen'):
return None
result = re.match(_screen_pattern, next_line) result = re.match(_screen_pattern, next_line)
if not result: if not result:
next_lines.append(next_line) next_lines.append(next_line)
@ -333,6 +356,10 @@ def _parse_device(next_lines: List[str], quiet: bool = False) -> Optional[Device
return None return None
next_line = next_lines.pop() next_line = next_lines.pop()
if _was_parsed(next_line, 'device'):
return None
result = re.match(_device_pattern, next_line) result = re.match(_device_pattern, next_line)
if not result: if not result:
next_lines.append(next_line) next_lines.append(next_line)
@ -402,6 +429,10 @@ def _parse_model(next_lines: List[str], quiet: bool = False) -> Optional[Model]:
return None return None
next_line = next_lines.pop() next_line = next_lines.pop()
if _was_parsed(next_line, 'model'):
return None
if not re.match(_edid_head_pattern, next_line): if not re.match(_edid_head_pattern, next_line):
next_lines.append(next_line) next_lines.append(next_line)
return None return None
@ -438,6 +469,7 @@ _frequencies_pattern = r"(((?P<frequency>\d+\.\d+)(?P<star>\*| |)(?P<plus>\+?)?)
def _parse_mode(line: str) -> Optional[Mode]: def _parse_mode(line: str) -> Optional[Mode]:
result = re.match(_mode_pattern, line) result = re.match(_mode_pattern, line)
frequencies: List[Frequency] = [] frequencies: List[Frequency] = []
if not result: if not result:
return None return None

View File

@ -18,13 +18,17 @@ from jc.parsers.xrandr import (
Mode, Mode,
Model, Model,
Device, Device,
Screen, Screen
) )
import jc.parsers.xrandr
import pprint import pprint
class XrandrTests(unittest.TestCase): class XrandrTests(unittest.TestCase):
def setUp(self):
jc.parsers.xrandr.parse_state = {}
def test_xrandr_nodata(self): def test_xrandr_nodata(self):
""" """
Test 'xrandr' with no data Test 'xrandr' with no data
@ -287,6 +291,7 @@ class XrandrTests(unittest.TestCase):
"serial_number": "0", "serial_number": "0",
} }
jc.parsers.xrandr.parse_state = {}
actual: Optional[Model] = _parse_model(generic_edid) actual: Optional[Model] = _parse_model(generic_edid)
self.assertIsNotNone(actual) self.assertIsNotNone(actual)