Skip to content

Commit

Permalink
Move count_brackets() to specfile.utils
Browse files Browse the repository at this point in the history
Signed-off-by: Nikola Forró <[email protected]>
  • Loading branch information
nforro committed Sep 26, 2024
1 parent 514fbde commit f5a4e59
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 31 deletions.
31 changes: 1 addition & 30 deletions specfile/macro_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from specfile.conditions import process_conditions
from specfile.formatter import formatted
from specfile.types import SupportsIndex
from specfile.utils import UserList
from specfile.utils import UserList, count_brackets

if TYPE_CHECKING:
from specfile.specfile import Specfile
Expand Down Expand Up @@ -303,35 +303,6 @@ def pop(lines):
else:
return line

def count_brackets(s):
bc = pc = 0
chars = list(s)
while chars:
c = chars.pop(0)
if c == "\\" and chars:
chars.pop(0)
continue
if c == "%" and chars:
c = chars.pop(0)
if c == "{":
bc += 1
elif c == "(":
pc += 1
continue
if c == "{" and bc > 0:
bc += 1
continue
if c == "}" and bc > 0:
bc -= 1
continue
if c == "(" and pc > 0:
pc += 1
continue
if c == ")" and pc > 0:
pc -= 1
continue
return bc, pc

md_regex = re.compile(
r"""
^
Expand Down
39 changes: 39 additions & 0 deletions specfile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,45 @@ def get_filename_from_location(location: str) -> str:
return location[slash + 1 :].split("=")[-1]


def count_brackets(string: str) -> Tuple[int, int]:
"""
Counts non-pair brackets in %{...} and %(...) expressions appearing in the given string.
Args:
string: Input string.
Returns:
The count of non-pair curly braces and the count of non-pair parentheses.
"""
bc = pc = 0
chars = list(string)
while chars:
c = chars.pop(0)
if c == "\\" and chars:
chars.pop(0)
continue
if c == "%" and chars:
c = chars.pop(0)
if c == "{":
bc += 1
elif c == "(":
pc += 1
continue
if c == "{" and bc > 0:
bc += 1
continue
if c == "}" and bc > 0:
bc -= 1
continue
if c == "(" and pc > 0:
pc += 1
continue
if c == ")" and pc > 0:
pc -= 1
continue
return bc, pc


def split_conditional_macro_expansion(value: str) -> Tuple[str, str, str]:
"""
Splits conditional macro expansion into its body and prefix and suffix of it.
Expand Down
19 changes: 18 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from specfile.utils import EVR, NEVR, NEVRA, get_filename_from_location
from specfile.utils import EVR, NEVR, NEVRA, count_brackets, get_filename_from_location


@pytest.mark.parametrize(
Expand Down Expand Up @@ -32,6 +32,23 @@ def test_get_filename_from_location(location, filename):
assert get_filename_from_location(location) == filename


@pytest.mark.parametrize(
"string, count",
[
("", (0, 0)),
("%macro", (0, 0)),
("%{macro}", (0, 0)),
("%{{macro}}", (0, 0)),
("%{{macro}", (1, 0)),
("%{macro:", (1, 0)),
("%(echo %{v}", (0, 1)),
("%(echo %{v} | cut -d. -f3)", (0, 0)),
],
)
def test_count_brackets(string, count):
assert count_brackets(string) == count


def test_EVR_compare():
assert EVR(version="0") == EVR(version="0")
assert EVR(version="0", release="1") != EVR(version="0", release="2")
Expand Down

0 comments on commit f5a4e59

Please sign in to comment.