* ext/tk/lib/tk.rb: properly treat a Tcl/Tk's string with escaping

special characters.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2004-02-11 14:31:33 +00:00
Родитель 6aca74c713
Коммит 6283babd21
2 изменённых файлов: 113 добавлений и 25 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Wed Feb 11 23:24:22 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: properly treat a Tcl/Tk's string with escaping
special characters.
Tue Feb 10 20:49:07 2004 Nobuyoshi Nakada <nobu@ruby-lang.org> Tue Feb 10 20:49:07 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (method_proc): return bound Proc object. [ruby-dev:22854] * eval.c (method_proc): return bound Proc object. [ruby-dev:22854]

Просмотреть файл

@ -87,9 +87,9 @@ module TkComm
#return Tk_CMDTBL[$1] #return Tk_CMDTBL[$1]
return TkCore::INTERP.tk_cmd_tbl[$1] return TkCore::INTERP.tk_cmd_tbl[$1]
end end
if val.include? ?\s #if val.include? ?\s
return val.split.collect{|v| tk_tcl2ruby(v)} # return val.split.collect{|v| tk_tcl2ruby(v)}
end #end
case val case val
when /^@font/ when /^@font/
TkFont.get_obj(val) TkFont.get_obj(val)
@ -101,17 +101,50 @@ module TkComm
TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val) TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val)
when /^i\d+$/ when /^i\d+$/
TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val
when / / when /^-?\d+\.?\d*(e[-+]?\d+)?$/
val.to_f
when /[^\\] /
val.split.collect{|elt| val.split.collect{|elt|
tk_tcl2ruby(elt) tk_tcl2ruby(elt)
} }
when /^-?\d+\.?\d*(e[-+]?\d+)?$/ when /\\ /
val.to_f val.gsub(/\\ /, ' ')
else else
val val
end end
end end
def tk_split_list(str)
return [] if str == ""
list = []
token = nil
escape = false
brace = 0
str.split('').each {|c|
if c == '\\' && !escape
escape = true
token = (token || "") << c
next
end
brace += 1 if c == '{' && !escape
brace -= 1 if c == '}' && !escape
if brace == 0 && c == ' ' && !escape
list << token.gsub(/^\{(.*)\}$/, '\1') if token
token = nil
else
token = (token || "") << c
end
escape = false
}
list << token.gsub(/^\{(.*)\}$/, '\1') if token
if list.size == 1
tk_tcl2ruby(list[0].gsub(/\\(\{|})/, '\1'))
else
list.collect{|token| tk_split_list(token)}
end
end
=begin
def tk_split_list(str) def tk_split_list(str)
return [] if str == "" return [] if str == ""
idx = str.index('{') idx = str.index('{')
@ -130,11 +163,13 @@ module TkComm
list = [] if list == "" list = [] if list == ""
str = str[idx+1..-1] str = str[idx+1..-1]
i = -1 i = -1
escape = false
brace = 1 brace = 1
str.each_byte {|c| str.each_byte {|c|
i += 1 i += 1
brace += 1 if c == ?{ brace += 1 if c == ?{ && !escape
brace -= 1 if c == ?} brace -= 1 if c == ?} && !escape
escape = (c == ?\\)
break if brace == 0 break if brace == 0
} }
if str.size == i + 1 if str.size == i + 1
@ -148,7 +183,33 @@ module TkComm
list += tk_split_list(str[i+1..-1]) list += tk_split_list(str[i+1..-1])
list list
end end
=end
def tk_split_simplelist(str)
return [] if str == ""
list = []
token = nil
escape = false
brace = 0
str.split('').each {|c|
if c == '\\' && !escape
escape = true
next
end
brace += 1 if c == '{' && !escape
brace -= 1 if c == '}' && !escape
if brace == 0 && c == ' ' && !escape
list << token.gsub(/^\{(.*)\}$/, '\1') if token
token = nil
else
token = (token || "") << c
end
escape = false
}
list << token.gsub(/^\{(.*)\}$/, '\1') if token
list
end
=begin
def tk_split_simplelist(str) def tk_split_simplelist(str)
return [] if str == "" return [] if str == ""
idx = str.index('{') idx = str.index('{')
@ -160,11 +221,13 @@ module TkComm
list = str[0,idx].split list = str[0,idx].split
str = str[idx+1..-1] str = str[idx+1..-1]
i = -1 i = -1
escape = false
brace = 1 brace = 1
str.each_byte {|c| str.each_byte {|c|
i += 1 i += 1
brace += 1 if c == ?{ brace += 1 if c == ?{ && !escape
brace -= 1 if c == ?} brace -= 1 if c == ?} && !escape
escape = (c == ?\\)
break if brace == 0 break if brace == 0
} }
if i == 0 if i == 0
@ -172,11 +235,14 @@ module TkComm
elsif str[0, i] == ' ' elsif str[0, i] == ' '
list.push ' ' list.push ' '
else else
list.push str[0..i-1] #list.push str[0..i-1]
list.push(str[0..i-1].gsub(/\\(\{|})/, '\1'))
end end
list += tk_split_simplelist(str[i+1..-1]) list += tk_split_simplelist(str[i+1..-1])
list list
end end
=end
private :tk_tcl2ruby, :tk_split_list, :tk_split_simplelist private :tk_tcl2ruby, :tk_split_list, :tk_split_simplelist
def _symbolkey2str(keys) def _symbolkey2str(keys)
@ -236,7 +302,7 @@ module TkComm
def string(val) def string(val)
if val == "{}" if val == "{}"
'' ''
elsif val[0] == ?{ elsif val[0] == ?{ && val[-1] == ?}
val[1..-2] val[1..-2]
else else
val val
@ -748,6 +814,7 @@ module TkCore
end end
INTERP.add_tk_procs('rb_out', 'args', <<-'EOL') INTERP.add_tk_procs('rb_out', 'args', <<-'EOL')
regsub -all {\\} $args {\\\\} args
regsub -all {!} $args {\\!} args regsub -all {!} $args {\\!} args
regsub -all "{" $args "\\{" args regsub -all "{" $args "\\{" args
if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} { if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {
@ -897,7 +964,8 @@ module TkCore
end end
def rb_appsend(interp, async, *args) def rb_appsend(interp, async, *args)
args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')}
args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')}
args.push(').to_s"') args.push(').to_s"')
appsend(interp, async, 'ruby "(', *args) appsend(interp, async, 'ruby "(', *args)
end end
@ -912,7 +980,8 @@ module TkCore
end end
def rb_appsend_displayof(interp, win, async, *args) def rb_appsend_displayof(interp, win, async, *args)
args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')}
args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')}
args.push(').to_s"') args.push(').to_s"')
appsend_displayof(interp, win, async, 'ruby "(', *args) appsend_displayof(interp, win, async, 'ruby "(', *args)
end end
@ -1550,7 +1619,8 @@ module Tk
@@enc_buf = '__rb_encoding_buffer__' @@enc_buf = '__rb_encoding_buffer__'
def self.tk_escape(str) def self.tk_escape(str)
s = '"' + str.gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + str.gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + str.gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
TkCore::INTERP.__eval(Kernel.format('global %s; set %s %s', TkCore::INTERP.__eval(Kernel.format('global %s; set %s %s',
@@enc_buf, @@enc_buf, s)) @@enc_buf, @@enc_buf, s))
end end
@ -1859,23 +1929,30 @@ class TkVariable
# val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
# s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
val.each_with_index{|e,i| a.push(i); a.push(e)} val.each_with_index{|e,i| a.push(i); a.push(e)}
s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + array2tk_list(a).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
elsif val.kind_of?(Hash) elsif val.kind_of?(Hash)
#s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
# .gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[\[\]$"]/, '\\\\\&') + '"' .gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
else else
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s)) INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end end
=end =end
if val.kind_of?(Hash) if val.kind_of?(Hash)
#s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
# .gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[\[\]$"]/, '\\\\\&') + '"' .gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s)) INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s))
else else
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
end end
end end
@ -1933,7 +2010,8 @@ class TkVariable
def value=(val) def value=(val)
begin begin
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
rescue rescue
if INTERP._eval(Kernel.format('global %s; array exists %s', if INTERP._eval(Kernel.format('global %s; array exists %s',
@ -1945,12 +2023,15 @@ class TkVariable
elsif val.kind_of?(Array) elsif val.kind_of?(Array)
a = [] a = []
val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' #s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + a.join(" ").gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s',
@id, @id, @id, s)) @id, @id, @id, s))
elsif val.kind_of?(Hash) elsif val.kind_of?(Hash)
#s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
# .gsub(/[\[\]$"]/, '\\\\\&') + '"'
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[\[\]$"]/, '\\\\\&') + '"' .gsub(/[\[\]$\\"]/, '\\\\\&') + '"'
INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s',
@id, @id, @id, s)) @id, @id, @id, s))
else else
@ -1993,7 +2074,8 @@ class TkVariable
end end
def to_s def to_s
string(value).to_s #string(value).to_s
value
end end
def to_sym def to_sym
@ -2302,7 +2384,8 @@ class TkVarAccess<TkVariable
@id = varname @id = varname
TkVar_ID_TBL[@id] = self TkVar_ID_TBL[@id] = self
if val if val
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #" #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #"
s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' #"
INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
end end
end end