From 8a4eed2147af1980a4595e98f6457cf70196bf12 Mon Sep 17 00:00:00 2001 From: Daniel Harrison Date: Tue, 26 Nov 2019 22:17:07 +1100 Subject: [PATCH] Value parse (#68) * Fix parsing of value string to allow mismatched parenthesis inside [] brackets. * Improve readability of value parse fix. * Added additional test. * Soft fail when fcntl is missing, fallback to default screen size. --- tests/textfsm_test.py | 11 +++++++++++ textfsm/__init__.py | 2 +- textfsm/parser.py | 4 +++- textfsm/terminal.py | 8 ++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/textfsm_test.py b/tests/textfsm_test.py index 3719b4a..ea74f00 100755 --- a/tests/textfsm_test.py +++ b/tests/textfsm_test.py @@ -70,6 +70,17 @@ def testFSMValue(self): v.Parse, 'Value beer (boo)hoo)') + # Unbalanced parenthesis can exist if within square "[]" braces. + v = textfsm.TextFSMValue(options_class=textfsm.TextFSMOptions) + v.Parse('Value beer (boo[(]hoo)') + self.assertEqual(v.name, 'beer') + self.assertEqual(v.regex, '(boo[(]hoo)') + + # Escaped braces don't count. + self.assertRaises(textfsm.TextFSMTemplateError, + v.Parse, + 'Value beer (boo\[)\]hoo)') + # String function. v = textfsm.TextFSMValue(options_class=textfsm.TextFSMOptions) v.Parse('Value Required beer (boo(hoo))') diff --git a/textfsm/__init__.py b/textfsm/__init__.py index bfd0861..77cdcbb 100644 --- a/textfsm/__init__.py +++ b/textfsm/__init__.py @@ -10,4 +10,4 @@ """ from textfsm.parser import * -__version__ = '1.1.0' +__version__ = '1.1.1' diff --git a/textfsm/parser.py b/textfsm/parser.py index ba994a7..e892420 100755 --- a/textfsm/parser.py +++ b/textfsm/parser.py @@ -313,8 +313,10 @@ def Parse(self, value): raise TextFSMTemplateError( "Invalid Value name '%s' or name too long." % self.name) + square_brackets = r'[^\]?\[[^]]*\]' + regex_without_brackets = re.sub(square_brackets, '', self.regex) if (not re.match(r'^\(.*\)$', self.regex) or - self.regex.count('(') != self.regex.count(')')): + regex_without_brackets.count('(') != regex_without_brackets.count(')')): raise TextFSMTemplateError( "Value '%s' must be contained within a '()' pair." % self.regex) diff --git a/textfsm/terminal.py b/textfsm/terminal.py index 497d7e8..aa455cc 100755 --- a/textfsm/terminal.py +++ b/textfsm/terminal.py @@ -22,7 +22,11 @@ from __future__ import print_function from __future__ import unicode_literals -import fcntl +try: + # Import fails on Windows machines. + import fcntl +except (ImportError, ModuleNotFoundError): + pass import getopt import os import re @@ -173,7 +177,7 @@ def TerminalSize(): with open(os.ctermid()) as tty_instance: length_width = struct.unpack( 'hh', fcntl.ioctl(tty_instance.fileno(), termios.TIOCGWINSZ, '1234')) - except (IOError, OSError): + except (IOError, OSError, NameError): try: length_width = (int(os.environ['LINES']), int(os.environ['COLUMNS']))