def tokadd_string(func, term, paren)
awords = (func & STR_FUNC_AWORDS) != 0
escape = (func & STR_FUNC_ESCAPE) != 0
expand = (func & STR_FUNC_EXPAND) != 0
regexp = (func & STR_FUNC_REGEXP) != 0
symbol = (func & STR_FUNC_SYMBOL) != 0
paren_re = paren.nil? ? nil : Regexp.new(Regexp.escape(paren))
term_re = Regexp.new(Regexp.escape(term))
until src.eos? do
c = nil
handled = true
case
when self.nest == 0 && src.scan(term_re) then
src.pos -= 1
break
when paren_re && src.scan(paren_re) then
self.nest += 1
when src.scan(term_re) then
self.nest -= 1
when awords && src.scan(/\s/) then
src.pos -= 1
break
when expand && src.scan(/#(?=[\$\@\{])/) then
src.pos -= 1
break
when expand && src.scan(/#(?!\n)/) then
when src.check(/\\/) then
case
when awords && src.scan(/\\\n/) then
string_buffer << "\n"
next
when awords && src.scan(/\\\s/) then
c = ' '
when expand && src.scan(/\\\n/) then
next
when regexp && src.check(/\\/) then
self.tokadd_escape term
next
when expand && src.scan(/\\/) then
c = self.read_escape
when src.scan(/\\\n/) then
when src.scan(/\\\\/) then
string_buffer << '\\' if escape
c = '\\'
when src.scan(/\\/) then
unless src.scan(term_re) || paren.nil? || src.scan(paren_re) then
string_buffer << "\\"
end
else
handled = false
end
else
handled = false
end
unless handled then
t = Regexp.escape term
x = Regexp.escape(paren) if paren && paren != "\000"
re = if awords then
/[^#{t}#{x}\#\0\\\n\ ]+|./
else
/[^#{t}#{x}\#\0\\]+|./
end
src.scan re
c = src.matched
rb_compile_error "symbol cannot contain '\\0'" if symbol && c =~ /\0/
end
c ||= src.matched
string_buffer << c
end
c ||= src.matched
c = RubyLexer::EOF if src.eos?
return c
end