Skip to content

Commit

Permalink
Add more expansion features
Browse files Browse the repository at this point in the history
Closes: #47
  • Loading branch information
sayanarijit committed Jun 30, 2021
1 parent e84a9f9 commit 4ee3f6d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
41 changes: 37 additions & 4 deletions expandvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ def expand_modifier_var(vars_, nounset, environ, var_symbol):
if vars_[0] == "!":
indirect = True
vars_ = vars_[1:]
elif vars_[0] == "#":
return expand_length(
vars_[1:], nounset=nounset, environ=environ, var_symbol=var_symbol
)
else:
indirect = False

Expand Down Expand Up @@ -264,7 +268,7 @@ def expand_advanced(var, vars_, nounset, indirect, environ, var_symbol):
var, vars_[1:], nounset=nounset, environ=environ, var_symbol=var_symbol
)

return expand_offset(
return expand_with_offset(
var, vars_, nounset=nounset, environ=environ, var_symbol=var_symbol
)

Expand Down Expand Up @@ -292,7 +296,7 @@ def expand_strict(var, vars_, nounset, environ, var_symbol):
raise MissingClosingBrace("".join(buff))


def expand_offset(var, vars_, nounset, environ, var_symbol):
def expand_with_offset(var, vars_, nounset, environ, var_symbol):
"""Expand variable with offset."""

buff = []
Expand All @@ -306,7 +310,7 @@ def expand_offset(var, vars_, nounset, environ, var_symbol):
raise OperandExpected(var, offset_str)
else:
offset = int(offset_str)
return expand_length(
return expand_with_len(
var,
vars_[n:],
offset,
Expand All @@ -333,7 +337,7 @@ def expand_offset(var, vars_, nounset, environ, var_symbol):
raise MissingClosingBrace("".join(buff))


def expand_length(var, vars_, offset, nounset, environ, var_symbol):
def expand_with_len(var, vars_, offset, nounset, environ, var_symbol):
"""Expand variable with offset and length."""

buff = []
Expand Down Expand Up @@ -409,6 +413,35 @@ def expand_default(var, vars_, set_, nounset, indirect, environ, var_symbol):
raise MissingClosingBrace("".join(default))


def expand_length(vars_, nounset=False, environ=os.environ, var_symbol="$"):
"""Expand length of a variable."""

buff = []
for c in vars_:
if c == "}":
n = len(buff) + 1
var = "".join(buff)
val = getenv(
var, nounset=nounset, indirect=False, environ=environ, default=""
)
if val:
return str(len(val)) + expand(
vars_[n:], nounset=nounset, environ=environ, var_symbol=var_symbol
)
if RECOVER_NULL is not None:
return str(len(RECOVER_NULL)) + expand(
vars_[n:], nounset=nounset, environ=environ, var_symbol=var_symbol
)
raise ParameterNullOrNotSet(var, None)

if _valid_char(c):
buff.append(c)
else:
raise BadSubstitution(vars_)

raise MissingClosingBrace("".join(buff))


def expand(vars_, nounset=False, environ=os.environ, var_symbol="$"):
"""Expand variables Unix style.
Expand Down
27 changes: 27 additions & 0 deletions tests/test_expandvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,33 @@ def test_offset_length():
assert expandvars.expandvars("${FOO:-3:1}:bar") == "damnbigfoobar:bar"


@patch.dict(env, {"THREE": "abc", "FOUR": "abcd", "SIX": "abcdef"})
def test_length():
importlib.reload(expandvars)

assert expandvars.expandvars("${#THREE}") == "3"
assert expandvars.expandvars("${#THREE}${#FOUR}") == "34"
assert expandvars.expandvars("foo${#SIX}$SIX") == "foo6abcdef"


@patch.dict(env, {"FOO": "abcabbcd", "BAR": "xabcabbcd", "ABC": "abc"})
def test_pattern_substitution_startswith():
importlib.reload(expandvars)

assert expandvars.expandvars("${FOO#abc}") == "abbcd"
assert expandvars.expandvars("${FOO#a*c}") == "abbcd"
assert expandvars.expandvars("${FOO##a*c}") == "d"
assert expandvars.expandvars("${FOO#a?c}") == "abbcd"
assert expandvars.expandvars("${FOO##a?c}") == "abbcd"

assert expandvars.expandvars("${FOO#$ABC}") == "abbcd"
assert expandvars.expandvars("${FOO#${ABC}}") == "abbcd"

assert expandvars.expandvars("${BAR#abc}") == "xabcabbcd"
assert expandvars.expandvars("${BAR#a*c}") == "xabcabbcd"
assert expandvars.expandvars("${BAR##a*c}") == "xabcabbcd"


@patch.dict(env, {"FOO": "X", "X": "foo"})
def test_expandvars_indirection():
importlib.reload(expandvars)
Expand Down

0 comments on commit 4ee3f6d

Please sign in to comment.