From 3b3178a9c9ef56f658ca07dc526e0409ce1cd3df Mon Sep 17 00:00:00 2001 From: Sebastian Luther Date: Tue, 10 Aug 2010 10:10:58 +0200 Subject: [PATCH] portage.dep.paren_reduce: Remove redundant brackets --- pym/portage/dep/__init__.py | 27 ++++++++++++++++++---- pym/portage/tests/dep/test_paren_reduce.py | 16 ++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/pym/portage/dep/__init__.py b/pym/portage/dep/__init__.py index 19e347cfb..89b384a5b 100644 --- a/pym/portage/dep/__init__.py +++ b/pym/portage/dep/__init__.py @@ -84,11 +84,11 @@ def strip_empty(myarr): def paren_reduce(mystr): """ Take a string and convert all paren enclosed entities into sublists and - split the list elements by spaces. + split the list elements by spaces. All redundant brackets are removed. Example usage: - >>> paren_reduce('foobar foo ( bar baz )') - ['foobar', 'foo', ['bar', 'baz']] + >>> paren_reduce('foobar foo? ( bar baz )') + ['foobar', 'foo?', ['bar', 'baz']] @param mystr: The string to reduce @type mystr: String @@ -111,7 +111,26 @@ def paren_reduce(mystr): _("malformed syntax: '%s'") % mystr) if level > 0: level -= 1 - stack[level].append(stack.pop()) + l = stack.pop() + if l: + if not stack[level] or (stack[level][-1] != "||" and not stack[level][-1][-1] == "?"): + #Optimize: ( ( ... ) ) -> ( ... ) + stack[level].extend(l) + elif len(l) == 1 and stack[level][-1] == "||": + #Optimize: || ( A ) -> A + stack[level].pop() + stack[level].extend(l) + elif len(l) == 2 and (l[0] == "||" or l[0][-1] == "?") and stack[level][-1] in (l[0], "||"): + #Optimize: || ( || ( ... ) ) -> || ( ... ) + # foo? ( foo? ( ... ) ) -> foo? ( ... ) + # || ( foo? ( ... ) ) -> foo? ( ... ) + stack[level].pop() + stack[level].extend(l) + else: + stack[level].append(l) + else: + if stack[level] and (stack[level][-1] == "||" or stack[level][-1][-1] == "?"): + stack[level].pop() else: raise portage.exception.InvalidDependString( _("malformed syntax: '%s'") % mystr) diff --git a/pym/portage/tests/dep/test_paren_reduce.py b/pym/portage/tests/dep/test_paren_reduce.py index 3277ab58b..bd5f42584 100644 --- a/pym/portage/tests/dep/test_paren_reduce.py +++ b/pym/portage/tests/dep/test_paren_reduce.py @@ -11,12 +11,23 @@ class TestParenReduce(TestCase): test_cases = ( ( "A", ["A"]), - ( "( A )", [["A"]]), + ( "( A )", ["A"]), ( "|| ( A B )", [ "||", ["A", "B"] ]), ( "|| ( A || ( B C ) )", [ "||", ["A", "||", ["B", "C"]]]), ( "|| ( A || ( B C D ) )", [ "||", ["A", "||", ["B", "C", "D"]] ]), ( "|| ( A || ( B || ( C D ) E ) )", [ "||", ["A", "||", ["B", "||", ["C", "D"], "E"]] ]), ( "a? ( A )", ["a?", ["A"]]), + + ( "( || ( ( ( A ) B ) ) )", [ "||", ["A", "B"] ]), + ( "( || ( || ( ( A ) B ) ) )", [ "||", ["A", "B"] ]), + ( "( || ( || ( ( A ) B ) ) )", [ "||", ["A", "B"] ]), + ( "|| ( A )", ["A"]), + ( "( || ( || ( || ( A ) foo? ( B ) ) ) )", [ "||", ["A", "foo?", ["B"] ]]), + ( "( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", [ "||", ["bar?", ["A"], "foo?", ["B"] ]]), + ( "A || ( ) foo? ( ) B", ["A", "B"]), + + ( "|| ( A ) || ( B )", ["A", "B"]), + ( "foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]), ) test_cases_xfail = ( @@ -36,6 +47,9 @@ class TestParenReduce(TestCase): "|| ( A B || )", "a? A", + + ( "( || ( || || ( A ) foo? ( B ) ) )"), + ( "( || ( || bar? ( A ) foo? ( B ) ) )"), ) for dep_str, expected_result in test_cases: -- 2.26.2