shrub/nix/nixcrpkgs/support/expand_brackets.rb

44 lines
1.3 KiB
Ruby
Raw Normal View History

def expand_brackets_core(str, depth)
finished_parts = []
active_parts = [+'']
while true
if str.empty?
raise AnticipatedError, "Unmatched opening brace" if depth > 0
break
elsif str.start_with?('}')
str.slice!(0)
raise AnticipatedError, "Unmatched closing brace" if depth == 0
break
elsif str.start_with?('{')
# Recurse, which removes everything up to and
# including the matching closing brace.
str.slice!(0)
options = expand_brackets_core(str, depth + 1)
raise if options.empty?
active_parts = active_parts.flat_map { |p1|
options.map { |p2| p1 + p2 }
}
elsif str.start_with?(',')
raise AnticipatedError, "Comma at top level" if depth == 0
# Remove the comma, mark the parts we are working
# on as finished, and start a new part.
str.slice!(0)
finished_parts += active_parts
active_parts = ['']
else
part_length = str.index(/[{},]|$/)
raise if part_length < 1
part = str.slice!(0, part_length)
active_parts.each do |s|
s.insert(-1, part)
end
end
end
finished_parts + active_parts
end
# Expands something like "{a,b}{,.x}" to ["a", "a.x", "b", "b.x"]
def expand_brackets(str)
expand_brackets_core(str.dup, 0)
end