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']))