mirror of
https://github.com/samsonjs/csc360-a1-shell.git
synced 2026-04-27 14:57:43 +00:00
Preserve escaped dollar literals
This commit is contained in:
parent
52ef7cb7f5
commit
5172c60910
1 changed files with 28 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ require "shellwords"
|
||||||
module Shell
|
module Shell
|
||||||
class WordExpander
|
class WordExpander
|
||||||
ENV_VAR_REGEX = /\$(?:\{([^}]+)\}|(\w+)\b)/
|
ENV_VAR_REGEX = /\$(?:\{([^}]+)\}|(\w+)\b)/
|
||||||
|
ESCAPED_DOLLAR = "\u0001"
|
||||||
|
|
||||||
# Splits the given line into multiple words, performing the following transformations:
|
# Splits the given line into multiple words, performing the following transformations:
|
||||||
#
|
#
|
||||||
|
|
@ -11,13 +12,15 @@ module Shell
|
||||||
# - Tilde expansion, which means that ~ is expanded to $HOME
|
# - Tilde expansion, which means that ~ is expanded to $HOME
|
||||||
# - Glob expansion on files and directories
|
# - Glob expansion on files and directories
|
||||||
def expand(line)
|
def expand(line)
|
||||||
shellsplit(line)
|
protected_line = protect_escaped_dollars(line)
|
||||||
|
shellsplit(protected_line)
|
||||||
.map do |word|
|
.map do |word|
|
||||||
word
|
word
|
||||||
.gsub(ENV_VAR_REGEX) do
|
.gsub(ENV_VAR_REGEX) do
|
||||||
name = Regexp.last_match(2) || Regexp.last_match(1)
|
name = Regexp.last_match(2) || Regexp.last_match(1)
|
||||||
ENV.fetch(name)
|
ENV.fetch(name)
|
||||||
end
|
end
|
||||||
|
.tr(ESCAPED_DOLLAR, "$")
|
||||||
# TODO: expand globs
|
# TODO: expand globs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -94,5 +97,29 @@ module Shell
|
||||||
def expand_globs(word)
|
def expand_globs(word)
|
||||||
Dir.glob(word)
|
Dir.glob(word)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def protect_escaped_dollars(line)
|
||||||
|
output = +""
|
||||||
|
i = 0
|
||||||
|
while i < line.length
|
||||||
|
if line.getbyte(i) == "\\".ord
|
||||||
|
j = i + 1
|
||||||
|
j += 1 while j < line.length && line.getbyte(j) == "\\".ord
|
||||||
|
count = j - i
|
||||||
|
if j < line.length && line.getbyte(j) == "$".ord && count.odd?
|
||||||
|
output << ("\\" * (count - 1))
|
||||||
|
output << ESCAPED_DOLLAR
|
||||||
|
i = j + 1
|
||||||
|
else
|
||||||
|
output << ("\\" * count)
|
||||||
|
i = j
|
||||||
|
end
|
||||||
|
else
|
||||||
|
output << line[i]
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
output
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue